xref: /aosp_15_r20/external/grpc-grpc/test/core/tsi/alts/frame_protector/alts_counter_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 "src/core/tsi/alts/frame_protector/alts_counter.h"
20 
21 #include <gtest/gtest.h>
22 
23 #include <grpc/support/alloc.h>
24 #include <grpc/support/log.h>
25 
26 #include "src/core/lib/gprpp/crash.h"
27 #include "test/core/tsi/alts/crypt/gsec_test_util.h"
28 
29 const size_t kSmallCounterSize = 4;
30 const size_t kSmallOverflowSize = 1;
31 const size_t kGcmCounterSize = 12;
32 const size_t kGcmOverflowSize = 5;
33 
do_bytes_represent_client(alts_counter * ctr,unsigned char *,size_t size)34 static bool do_bytes_represent_client(alts_counter* ctr,
35                                       unsigned char* /*counter*/, size_t size) {
36   return (ctr->counter[size - 1] & 0x80) == 0x80;
37 }
38 
alts_counter_test_input_sanity_check(size_t counter_size,size_t overflow_size)39 static void alts_counter_test_input_sanity_check(size_t counter_size,
40                                                  size_t overflow_size) {
41   alts_counter* ctr = nullptr;
42   char* error_details = nullptr;
43 
44   // Input sanity check on alts_counter_create().
45   // Invalid counter size.
46   grpc_status_code status =
47       alts_counter_create(true, 0, overflow_size, &ctr, &error_details);
48   ASSERT_TRUE(gsec_test_expect_compare_code_and_substr(
49       status, GRPC_STATUS_INVALID_ARGUMENT, error_details,
50       "counter_size is invalid."));
51   gpr_free(error_details);
52 
53   // Invalid overflow size.
54   status = alts_counter_create(true, counter_size, 0, &ctr, &error_details);
55   ASSERT_TRUE(gsec_test_expect_compare_code_and_substr(
56       status, GRPC_STATUS_INVALID_ARGUMENT, error_details,
57       "overflow_size is invalid."));
58   gpr_free(error_details);
59 
60   // alts_counter is nullptr.
61   status = alts_counter_create(true, counter_size, overflow_size, nullptr,
62                                &error_details);
63   ASSERT_TRUE(gsec_test_expect_compare_code_and_substr(
64       status, GRPC_STATUS_INVALID_ARGUMENT, error_details,
65       "crypter_counter is nullptr."));
66   gpr_free(error_details);
67 
68   status = alts_counter_create(true, counter_size, overflow_size, &ctr,
69                                &error_details);
70   ASSERT_EQ(status, GRPC_STATUS_OK);
71 
72   // Input sanity check on alts_counter_increment().
73   // crypter_counter is nullptr.
74   bool is_overflow = false;
75   status = alts_counter_increment(nullptr, &is_overflow, &error_details);
76   ASSERT_TRUE(gsec_test_expect_compare_code_and_substr(
77       status, GRPC_STATUS_INVALID_ARGUMENT, error_details,
78       "crypter_counter is nullptr."));
79   gpr_free(error_details);
80   // is_overflow is nullptr.
81   status = alts_counter_increment(ctr, nullptr, &error_details);
82   ASSERT_TRUE(gsec_test_expect_compare_code_and_substr(
83       status, GRPC_STATUS_INVALID_ARGUMENT, error_details,
84       "is_overflow is nullptr."));
85   gpr_free(error_details);
86   alts_counter_destroy(ctr);
87 }
88 
alts_counter_test_overflow_full_range(bool is_client,size_t counter_size,size_t overflow_size)89 static void alts_counter_test_overflow_full_range(bool is_client,
90                                                   size_t counter_size,
91                                                   size_t overflow_size) {
92   alts_counter* ctr = nullptr;
93   char* error_details = nullptr;
94   grpc_status_code status = alts_counter_create(
95       is_client, counter_size, overflow_size, &ctr, &error_details);
96   ASSERT_EQ(status, GRPC_STATUS_OK);
97   unsigned char* expected =
98       static_cast<unsigned char*>(gpr_zalloc(counter_size));
99   if (is_client) {
100     expected[counter_size - 1] = 0x80;
101   }
102   // Do a single iteration to ensure the counter is initialized as expected.
103   ASSERT_EQ(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr),
104                                       counter_size),
105             is_client);
106   ASSERT_EQ(memcmp(alts_counter_get_counter(ctr), expected, counter_size), 0);
107   bool is_overflow = false;
108   ASSERT_EQ(alts_counter_increment(ctr, &is_overflow, &error_details),
109             GRPC_STATUS_OK);
110   ASSERT_FALSE(is_overflow);
111   ///
112   /// The counter can return 2^{overflow_size * 8} counters. The
113   /// high-order bit is fixed to the client/server. The last call will yield a
114   /// useable counter, but overflow the counter object.
115   ///
116   int iterations = 1 << (overflow_size * 8);
117   int ind = 1;
118   for (ind = 1; ind < iterations - 1; ind++) {
119     ASSERT_EQ(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr),
120                                         counter_size),
121               is_client);
122     ASSERT_EQ(alts_counter_increment(ctr, &is_overflow, &error_details),
123               GRPC_STATUS_OK);
124     ASSERT_FALSE(is_overflow);
125   }
126   ASSERT_EQ(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr),
127                                       counter_size),
128             is_client);
129   ASSERT_EQ(alts_counter_increment(ctr, &is_overflow, &error_details),
130             GRPC_STATUS_FAILED_PRECONDITION);
131   ASSERT_TRUE(is_overflow);
132   gpr_free(expected);
133   alts_counter_destroy(ctr);
134 }
135 
136 // Set the counter manually and make sure it overflows as expected.
alts_counter_test_overflow_single_increment(bool is_client,size_t counter_size,size_t overflow_size)137 static void alts_counter_test_overflow_single_increment(bool is_client,
138                                                         size_t counter_size,
139                                                         size_t overflow_size) {
140   alts_counter* ctr = nullptr;
141   char* error_details = nullptr;
142   grpc_status_code status = alts_counter_create(
143       is_client, counter_size, overflow_size, &ctr, &error_details);
144   ASSERT_EQ(status, GRPC_STATUS_OK);
145   unsigned char* expected =
146       static_cast<unsigned char*>(gpr_zalloc(counter_size));
147   memset(expected, 0xFF, overflow_size);
148   expected[0] = 0xFE;
149 
150   if (is_client) {
151     expected[counter_size - 1] = 0x80;
152   }
153   memcpy(ctr->counter, expected, counter_size);
154   ASSERT_EQ(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr),
155                                       counter_size),
156             is_client);
157   ASSERT_EQ(memcmp(expected, alts_counter_get_counter(ctr), counter_size), 0);
158   bool is_overflow = false;
159   ASSERT_EQ(alts_counter_increment(ctr, &is_overflow, &error_details),
160             GRPC_STATUS_OK);
161   ASSERT_FALSE(is_overflow);
162   ASSERT_EQ(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr),
163                                       counter_size),
164             is_client);
165   expected[0] = static_cast<unsigned char>(expected[0] + 1);
166   ASSERT_EQ(memcmp(expected, alts_counter_get_counter(ctr), counter_size), 0);
167   ASSERT_EQ(alts_counter_increment(ctr, &is_overflow, &error_details),
168             GRPC_STATUS_FAILED_PRECONDITION);
169   ASSERT_TRUE(is_overflow);
170   gpr_free(expected);
171   alts_counter_destroy(ctr);
172 }
173 
TEST(AltsCounterTest,MainTest)174 TEST(AltsCounterTest, MainTest) {
175   alts_counter_test_input_sanity_check(kGcmCounterSize, kGcmOverflowSize);
176   alts_counter_test_overflow_full_range(true, kSmallCounterSize,
177                                         kSmallOverflowSize);
178   alts_counter_test_overflow_full_range(false, kSmallCounterSize,
179                                         kSmallOverflowSize);
180   alts_counter_test_overflow_single_increment(true, kGcmCounterSize,
181                                               kGcmOverflowSize);
182   alts_counter_test_overflow_single_increment(false, kGcmCounterSize,
183                                               kGcmOverflowSize);
184 }
185 
main(int argc,char ** argv)186 int main(int argc, char** argv) {
187   ::testing::InitGoogleTest(&argc, argv);
188   return RUN_ALL_TESTS();
189 }
190