blob: 661a81024aca1dc1b275e0160407da1f5c1deec2 [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
79TEST(TlvTests, decodeBadRecords)
80{
81 struct tlv_const_iterator iter;
82 struct tlv_record decoded_record;
83
84 /* Case 1: Too short to accommodate a valid header */
85 const uint8_t case_1[] = {
86 0x77, 0x31, 0x00
87 };
88
89 tlv_const_iterator_begin(&iter, case_1, sizeof(case_1));
90 CHECK_FALSE(tlv_decode(&iter, &decoded_record));
91
92 /* Case 1: A complete record followed by a truncated one */
93 const uint8_t case_2[] = {
94 0x77, 0x31, 0x00, 0x00,
95 0x03, 0x21, 0x00, 0x03, 0xaa
96 };
97
98 tlv_const_iterator_begin(&iter, case_2, sizeof(case_2));
99 CHECK_TRUE(tlv_decode(&iter, &decoded_record));
100 CHECK_FALSE(tlv_decode(&iter, &decoded_record));
101}
102
103TEST(TlvTests, encodeRecords)
104{
105 struct tlv_iterator iter;
106 struct tlv_record record_to_encode;
107 size_t required_space;
108
109 /* Case 1: Encode zero length record */
110 const uint8_t case_1_expected[] = {
111 0x66, 0x77, 0x00, 0x00
112 };
113 record_to_encode.tag = 0x6677;
114 record_to_encode.length = 0;
115 record_to_encode.value = NULL;
116 required_space = tlv_required_space(record_to_encode.length);
117 uint8_t case_1_actual[required_space];
118 tlv_iterator_begin(&iter, case_1_actual, required_space);
119 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
120 MEMCMP_EQUAL(case_1_expected, case_1_actual, required_space);
121
122 /* Case 2: Encode two records */
123 const uint8_t case_2_expected[] = {
124 0xa8, 0xa9, 0x00, 0x01, 0x88,
125 0xa8, 0xaa, 0x00, 0x02, 0x01, 0x02
126 };
127
128 required_space = tlv_required_space(1) + tlv_required_space(2);
129 uint8_t case_2_actual[required_space];
130 tlv_iterator_begin(&iter, case_2_actual, required_space);
131
132 record_to_encode.tag = 0xa8a9;
133 record_to_encode.length = 1;
134 record_to_encode.value = &case_2_expected[4];
135 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
136
137 record_to_encode.tag = 0xa8aa;
138 record_to_encode.length = 2;
139 record_to_encode.value = &case_2_expected[9];
140 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
141
142 MEMCMP_EQUAL(case_2_expected, case_2_actual, required_space);
143
144 /* Check that you can't encode beyond the limit of the buffer */
145 CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
146}
147
148TEST(TlvTests, encodeInsufficientSpace)
149{
150 struct tlv_iterator iter;
151 struct tlv_record record_to_encode;
152 size_t required_space;
153
154 /* Case 1: Encode record into buffer that isn't big enough */
155 const uint8_t case_1_expected[] = {
156 0x66, 0x77, 0x00, 0x03, 0x01, 0x02, 0x03
157 };
158 record_to_encode.tag = 0x6677;
159 record_to_encode.length = 3;
160 record_to_encode.value = &case_1_expected[4];
161 required_space = tlv_required_space(record_to_encode.length) - 1;
162 uint8_t case_1_actual[required_space];
163 tlv_iterator_begin(&iter, case_1_actual, required_space);
164 CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
165}
166
167TEST(TlvTests, encodeWrongOrder)
168{
169 struct tlv_iterator iter;
170 struct tlv_record record_to_encode;
171 size_t required_space;
172
173 /* Check defence against encoding successive records
174 * out of tag value order. Encoding rules require
175 * records to be in ascending tag value order.
176 */
177 const uint8_t record_value[] = {
178 0x11, 0x22, 0x33, 0x44
179 };
180
181 /* Attemps to encode 4 records, the first 3 obey order
182 * rule, the last one doesn't
183 */
184 required_space = tlv_required_space(sizeof(record_value)) * 4;
185 uint8_t encode_buffer[required_space];
186 tlv_iterator_begin(&iter, encode_buffer, required_space);
187
188 record_to_encode.tag = 1;
189 record_to_encode.length = sizeof(record_value);
190 record_to_encode.value = record_value;
191 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
192
193 record_to_encode.tag = 2;
194 record_to_encode.length = sizeof(record_value);
195 record_to_encode.value = record_value;
196 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
197
198 record_to_encode.tag = 2;
199 record_to_encode.length = sizeof(record_value);
200 record_to_encode.value = record_value;
201 CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
202
203 record_to_encode.tag = 1;
204 record_to_encode.length = sizeof(record_value);
205 record_to_encode.value = record_value;
206 CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
207}