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/frame_protector/alts_counter.h" 22 23 #include <string.h> 24 25 #include <grpc/support/alloc.h> 26 27 static void maybe_copy_error_msg(const char* src, char** dst) { 28 if (dst != nullptr && src != nullptr) { 29 *dst = static_cast<char*>(gpr_malloc(strlen(src) + 1)); 30 memcpy(*dst, src, strlen(src) + 1); 31 } 32 } 33 34 grpc_status_code alts_counter_create(bool is_client, size_t counter_size, 35 size_t overflow_size, 36 alts_counter** crypter_counter, 37 char** error_details) { 38 /* Perform input sanity check. */ 39 if (counter_size == 0) { 40 const char error_msg[] = "counter_size is invalid."; 41 maybe_copy_error_msg(error_msg, error_details); 42 return GRPC_STATUS_INVALID_ARGUMENT; 43 } 44 if (overflow_size == 0 || overflow_size >= counter_size) { 45 const char error_msg[] = "overflow_size is invalid."; 46 maybe_copy_error_msg(error_msg, error_details); 47 return GRPC_STATUS_INVALID_ARGUMENT; 48 } 49 if (crypter_counter == nullptr) { 50 const char error_msg[] = "crypter_counter is nullptr."; 51 maybe_copy_error_msg(error_msg, error_details); 52 return GRPC_STATUS_INVALID_ARGUMENT; 53 } 54 *crypter_counter = 55 static_cast<alts_counter*>(gpr_malloc(sizeof(**crypter_counter))); 56 (*crypter_counter)->size = counter_size; 57 (*crypter_counter)->overflow_size = overflow_size; 58 (*crypter_counter)->counter = 59 static_cast<unsigned char*>(gpr_zalloc(counter_size)); 60 if (is_client) { 61 ((*crypter_counter)->counter)[counter_size - 1] = 0x80; 62 } 63 return GRPC_STATUS_OK; 64 } 65 66 grpc_status_code alts_counter_increment(alts_counter* crypter_counter, 67 bool* is_overflow, 68 char** error_details) { 69 /* Perform input sanity check. */ 70 if (crypter_counter == nullptr) { 71 const char error_msg[] = "crypter_counter is nullptr."; 72 maybe_copy_error_msg(error_msg, error_details); 73 return GRPC_STATUS_INVALID_ARGUMENT; 74 } 75 if (is_overflow == nullptr) { 76 const char error_msg[] = "is_overflow is nullptr."; 77 maybe_copy_error_msg(error_msg, error_details); 78 return GRPC_STATUS_INVALID_ARGUMENT; 79 } 80 /* Increment the internal counter. */ 81 size_t i = 0; 82 for (; i < crypter_counter->overflow_size; i++) { 83 (crypter_counter->counter)[i]++; 84 if ((crypter_counter->counter)[i] != 0x00) { 85 break; 86 } 87 } 88 /** 89 * If the lower overflow_size bytes are all zero, the counter has overflowed. 90 */ 91 if (i == crypter_counter->overflow_size) { 92 *is_overflow = true; 93 return GRPC_STATUS_FAILED_PRECONDITION; 94 } 95 *is_overflow = false; 96 return GRPC_STATUS_OK; 97 } 98 99 size_t alts_counter_get_size(alts_counter* crypter_counter) { 100 if (crypter_counter == nullptr) { 101 return 0; 102 } 103 return crypter_counter->size; 104 } 105 106 unsigned char* alts_counter_get_counter(alts_counter* crypter_counter) { 107 if (crypter_counter == nullptr) { 108 return nullptr; 109 } 110 return crypter_counter->counter; 111 } 112 113 void alts_counter_destroy(alts_counter* crypter_counter) { 114 if (crypter_counter != nullptr) { 115 gpr_free(crypter_counter->counter); 116 gpr_free(crypter_counter); 117 } 118 } 119