blob: 5d8a50d219cf68a69f163265eb30d6281fad17a2 [file] [log] [blame]
julhal01734dbad2020-12-21 10:27:41 +00001/*
2 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <cstring>
8#include <common/tlv/tlv.h>
9#include <CppUTest/TestHarness.h>
10
11TEST_GROUP(TlvTests)
12{
13
14};
15
16TEST(TlvTests, decodeGoodRecords)
17{
18 struct tlv_const_iterator iter;
19 struct tlv_record decoded_record;
20
21 /* Case 1: Valid single zero length record */
22 const uint8_t case_1[] = {
23 0x77, 0x31, 0x00, 0x00
24 };
25
26 tlv_const_iterator_begin(&iter, case_1, sizeof(case_1));
27 CHECK_TRUE(tlv_decode(&iter, &decoded_record));
28 UNSIGNED_LONGS_EQUAL(0x7731, decoded_record.tag);
29 UNSIGNED_LONGS_EQUAL(0, decoded_record.length);
30 CHECK_FALSE(tlv_decode(&iter, &decoded_record));
31
32 /* Case 2: Two valid records */
33 const uint8_t case_2[] = {
34 0x01, 0x10, 0x00, 0x01, 0x50,
35 0x02, 0x11, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04
36 };
37
38 tlv_const_iterator_begin(&iter, case_2, sizeof(case_2));
39 CHECK_TRUE(tlv_decode(&iter, &decoded_record));
40 UNSIGNED_LONGS_EQUAL(0x0110, decoded_record.tag);
41 UNSIGNED_LONGS_EQUAL(1, decoded_record.length);
42 UNSIGNED_LONGS_EQUAL(0x50, decoded_record.value[0]);
43 CHECK_TRUE(tlv_decode(&iter, &decoded_record));
44 UNSIGNED_LONGS_EQUAL(0x0211, decoded_record.tag);
45 UNSIGNED_LONGS_EQUAL(4, decoded_record.length);
46 UNSIGNED_LONGS_EQUAL(0x01, decoded_record.value[0]);
47 UNSIGNED_LONGS_EQUAL(0x02, decoded_record.value[1]);
48 UNSIGNED_LONGS_EQUAL(0x03, decoded_record.value[2]);
49 UNSIGNED_LONGS_EQUAL(0x04, decoded_record.value[3]);
50 CHECK_FALSE(tlv_decode(&iter, &decoded_record));
51}
52
53TEST(TlvTests, findAndDecode)
54{
55 struct tlv_const_iterator iter;
56 struct tlv_record decoded_record;
57
58 /*
59 * Checks use of the tlv_find_decode method to extract known records
60 * from a sequence of records, encoded in ascending tag order, that includes
61 * ones that the receiver isn't interested in.
62 */
63 const uint8_t encoded_records[] = {
64 0x00, 0x01, 0x00, 0x00,
65 0x00, 0x02, 0x00, 0x03, 0x88, 0x88, 0x88,
66 0x00, 0x07, 0x00, 0x02, 0x77, 0x77,
67 0x00, 0x09, 0x00, 0x01, 0x77
68 };
69
70 tlv_const_iterator_begin(&iter, encoded_records, sizeof(encoded_records));
71 CHECK_TRUE(tlv_find_decode(&iter, 0x0001, &decoded_record));
72 UNSIGNED_LONGS_EQUAL(0, decoded_record.length);
73 CHECK_TRUE(tlv_find_decode(&iter, 0x0007, &decoded_record));
74 UNSIGNED_LONGS_EQUAL(2, decoded_record.length);
75 CHECK_TRUE(tlv_find_decode(&iter, 0x0009, &decoded_record));
76 UNSIGNED_LONGS_EQUAL(1, decoded_record.length);
77}
78
julhal013ec4c322021-02-05 17:30:49 +000079TEST(TlvTests, findAndDecodeMissingOptional)
80{
81 struct tlv_const_iterator iter;
82 struct tlv_record decoded_record;
83
84 /*
85 * Checks finding a missing record is correctly
86 * identified as not present but that the following
87 * record is found.
88 */
89 const uint8_t encoded_records[] = {
90 0x00, 0x07, 0x00, 0x02, 0x77, 0x77
91 };
92
93 tlv_const_iterator_begin(&iter, encoded_records, sizeof(encoded_records));
94 CHECK(!tlv_find_decode(&iter, 0x0001, &decoded_record));
95 CHECK(tlv_find_decode(&iter, 0x0007, &decoded_record));
96 CHECK_EQUAL(2, decoded_record.length);
97}
98
julhal01734dbad2020-12-21 10:27:41 +000099TEST(TlvTests, decodeBadRecords)
100{
101 struct tlv_const_iterator iter;
102 struct tlv_record decoded_record;
103
104 /* Case 1: Too short to accommodate a valid header */
105 const uint8_t case_1[] = {
106 0x77, 0x31, 0x00
107 };
108
109 tlv_const_iterator_begin(&iter, case_1, sizeof(case_1));
110 CHECK_FALSE(tlv_decode(&iter, &decoded_record));
111
112 /* Case 1: A complete record followed by a truncated one */
113 const uint8_t case_2[] = {
114 0x77, 0x31, 0x00, 0x00,
115 0x03, 0x21, 0x00, 0x03, 0xaa
116 };
117
118 tlv_const_iterator_begin(&iter, case_2, sizeof(case_2));
119 CHECK_TRUE(tlv_decode(&iter, &decoded_record));
120 CHECK_FALSE(tlv_decode(&iter, &decoded_record));
121}
122
123TEST(TlvTests, encodeRecords)
124{
125 struct tlv_iterator iter;
126 struct tlv_record record_to_encode;
127 size_t required_space;
128
129 /* Case 1: Encode zero length record */
130 const uint8_t case_1_expected[] = {
131 0x66, 0x77, 0x00, 0x00
132 };
133 record_to_encode.tag = 0x6677;
134 record_to_encode.length = 0;
135 record_to_encode.value = NULL;
136 required_space = tlv_required_space(record_to_encode.length);
137 uint8_t case_1_actual[required_space];
138 tlv_iterator_begin(&iter, case_1_actual, required_space);
139 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
140 MEMCMP_EQUAL(case_1_expected, case_1_actual, required_space);
141
142 /* Case 2: Encode two records */
143 const uint8_t case_2_expected[] = {
144 0xa8, 0xa9, 0x00, 0x01, 0x88,
145 0xa8, 0xaa, 0x00, 0x02, 0x01, 0x02
146 };
147
148 required_space = tlv_required_space(1) + tlv_required_space(2);
149 uint8_t case_2_actual[required_space];
150 tlv_iterator_begin(&iter, case_2_actual, required_space);
151
152 record_to_encode.tag = 0xa8a9;
153 record_to_encode.length = 1;
154 record_to_encode.value = &case_2_expected[4];
155 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
156
157 record_to_encode.tag = 0xa8aa;
158 record_to_encode.length = 2;
159 record_to_encode.value = &case_2_expected[9];
160 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
161
162 MEMCMP_EQUAL(case_2_expected, case_2_actual, required_space);
163
164 /* Check that you can't encode beyond the limit of the buffer */
165 CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
166}
167
168TEST(TlvTests, encodeInsufficientSpace)
169{
170 struct tlv_iterator iter;
171 struct tlv_record record_to_encode;
172 size_t required_space;
173
174 /* Case 1: Encode record into buffer that isn't big enough */
175 const uint8_t case_1_expected[] = {
176 0x66, 0x77, 0x00, 0x03, 0x01, 0x02, 0x03
177 };
178 record_to_encode.tag = 0x6677;
179 record_to_encode.length = 3;
180 record_to_encode.value = &case_1_expected[4];
181 required_space = tlv_required_space(record_to_encode.length) - 1;
182 uint8_t case_1_actual[required_space];
183 tlv_iterator_begin(&iter, case_1_actual, required_space);
184 CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
185}
186
187TEST(TlvTests, encodeWrongOrder)
188{
189 struct tlv_iterator iter;
190 struct tlv_record record_to_encode;
191 size_t required_space;
192
193 /* Check defence against encoding successive records
194 * out of tag value order. Encoding rules require
195 * records to be in ascending tag value order.
196 */
197 const uint8_t record_value[] = {
198 0x11, 0x22, 0x33, 0x44
199 };
200
201 /* Attemps to encode 4 records, the first 3 obey order
202 * rule, the last one doesn't
203 */
204 required_space = tlv_required_space(sizeof(record_value)) * 4;
205 uint8_t encode_buffer[required_space];
206 tlv_iterator_begin(&iter, encode_buffer, required_space);
207
208 record_to_encode.tag = 1;
209 record_to_encode.length = sizeof(record_value);
210 record_to_encode.value = record_value;
211 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
212
213 record_to_encode.tag = 2;
214 record_to_encode.length = sizeof(record_value);
215 record_to_encode.value = record_value;
216 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
217
218 record_to_encode.tag = 2;
219 record_to_encode.length = sizeof(record_value);
220 record_to_encode.value = record_value;
221 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
222
223 record_to_encode.tag = 1;
224 record_to_encode.length = sizeof(record_value);
225 record_to_encode.value = record_value;
226 CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
227}