1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/net/http/hpack.h>
8 #include <zephyr/net/net_ip.h>
9 #include <zephyr/ztest.h>
10 
11 struct huffman_codes {
12 	uint32_t code;
13 	uint8_t bitlen;
14 };
15 
16 /* Copy-paste from RFC7541. */
17 static struct huffman_codes test_huffman_codes[] = {
18 	{     0x1ff8, 13, }, {   0x7fffd8, 23, }, {  0xfffffe2, 28, }, {  0xfffffe3, 28, },
19 	{  0xfffffe4, 28, }, {  0xfffffe5, 28, }, {  0xfffffe6, 28, }, {  0xfffffe7, 28, },
20 	{  0xfffffe8, 28, }, {   0xffffea, 24, }, { 0x3ffffffc, 30, }, {  0xfffffe9, 28, },
21 	{  0xfffffea, 28, }, { 0x3ffffffd, 30, }, {  0xfffffeb, 28, }, {  0xfffffec, 28, },
22 	{  0xfffffed, 28, }, {  0xfffffee, 28, }, {  0xfffffef, 28, }, {  0xffffff0, 28, },
23 	{  0xffffff1, 28, }, {  0xffffff2, 28, }, { 0x3ffffffe, 30, }, {  0xffffff3, 28, },
24 	{  0xffffff4, 28, }, {  0xffffff5, 28, }, {  0xffffff6, 28, }, {  0xffffff7, 28, },
25 	{  0xffffff8, 28, }, {  0xffffff9, 28, }, {  0xffffffa, 28, }, {  0xffffffb, 28, },
26 	{       0x14,  6, }, {      0x3f8, 10, }, {      0x3f9, 10, }, {      0xffa, 12, },
27 	{     0x1ff9, 13, }, {       0x15,  6, }, {       0xf8,  8, }, {      0x7fa, 11, },
28 	{      0x3fa, 10, }, {      0x3fb, 10, }, {       0xf9,  8, }, {      0x7fb, 11, },
29 	{       0xfa,  8, }, {       0x16,  6, }, {       0x17,  6, }, {       0x18,  6, },
30 	{        0x0,  5, }, {        0x1,  5, }, {        0x2,  5, }, {       0x19,  6, },
31 	{       0x1a,  6, }, {       0x1b,  6, }, {       0x1c,  6, }, {       0x1d,  6, },
32 	{       0x1e,  6, }, {       0x1f,  6, }, {       0x5c,  7, }, {       0xfb,  8, },
33 	{     0x7ffc, 15, }, {       0x20,  6, }, {      0xffb, 12, }, {      0x3fc, 10, },
34 	{     0x1ffa, 13, }, {       0x21,  6, }, {       0x5d,  7, }, {       0x5e,  7, },
35 	{       0x5f,  7, }, {       0x60,  7, }, {       0x61,  7, }, {       0x62,  7, },
36 	{       0x63,  7, }, {       0x64,  7, }, {       0x65,  7, }, {       0x66,  7, },
37 	{       0x67,  7, }, {       0x68,  7, }, {       0x69,  7, }, {       0x6a,  7, },
38 	{       0x6b,  7, }, {       0x6c,  7, }, {       0x6d,  7, }, {       0x6e,  7, },
39 	{       0x6f,  7, }, {       0x70,  7, }, {       0x71,  7, }, {       0x72,  7, },
40 	{       0xfc,  8, }, {       0x73,  7, }, {       0xfd,  8, }, {     0x1ffb, 13, },
41 	{    0x7fff0, 19, }, {     0x1ffc, 13, }, {     0x3ffc, 14, }, {       0x22,  6, },
42 	{     0x7ffd, 15, }, {        0x3,  5, }, {       0x23,  6, }, {        0x4,  5, },
43 	{       0x24,  6, }, {        0x5,  5, }, {       0x25,  6, }, {       0x26,  6, },
44 	{       0x27,  6, }, {        0x6,  5, }, {       0x74,  7, }, {       0x75,  7, },
45 	{       0x28,  6, }, {       0x29,  6, }, {       0x2a,  6, }, {        0x7,  5, },
46 	{       0x2b,  6, }, {       0x76,  7, }, {       0x2c,  6, }, {        0x8,  5, },
47 	{        0x9,  5, }, {       0x2d,  6, }, {       0x77,  7, }, {       0x78,  7, },
48 	{       0x79,  7, }, {       0x7a,  7, }, {       0x7b,  7, }, {     0x7ffe, 15, },
49 	{      0x7fc, 11, }, {     0x3ffd, 14, }, {     0x1ffd, 13, }, {  0xffffffc, 28, },
50 	{    0xfffe6, 20, }, {   0x3fffd2, 22, }, {    0xfffe7, 20, }, {    0xfffe8, 20, },
51 	{   0x3fffd3, 22, }, {   0x3fffd4, 22, }, {   0x3fffd5, 22, }, {   0x7fffd9, 23, },
52 	{   0x3fffd6, 22, }, {   0x7fffda, 23, }, {   0x7fffdb, 23, }, {   0x7fffdc, 23, },
53 	{   0x7fffdd, 23, }, {   0x7fffde, 23, }, {   0xffffeb, 24, }, {   0x7fffdf, 23, },
54 	{   0xffffec, 24, }, {   0xffffed, 24, }, {   0x3fffd7, 22, }, {   0x7fffe0, 23, },
55 	{   0xffffee, 24, }, {   0x7fffe1, 23, }, {   0x7fffe2, 23, }, {   0x7fffe3, 23, },
56 	{   0x7fffe4, 23, }, {   0x1fffdc, 21, }, {   0x3fffd8, 22, }, {   0x7fffe5, 23, },
57 	{   0x3fffd9, 22, }, {   0x7fffe6, 23, }, {   0x7fffe7, 23, }, {   0xffffef, 24, },
58 	{   0x3fffda, 22, }, {   0x1fffdd, 21, }, {    0xfffe9, 20, }, {   0x3fffdb, 22, },
59 	{   0x3fffdc, 22, }, {   0x7fffe8, 23, }, {   0x7fffe9, 23, }, {   0x1fffde, 21, },
60 	{   0x7fffea, 23, }, {   0x3fffdd, 22, }, {   0x3fffde, 22, }, {   0xfffff0, 24, },
61 	{   0x1fffdf, 21, }, {   0x3fffdf, 22, }, {   0x7fffeb, 23, }, {   0x7fffec, 23, },
62 	{   0x1fffe0, 21, }, {   0x1fffe1, 21, }, {   0x3fffe0, 22, }, {   0x1fffe2, 21, },
63 	{   0x7fffed, 23, }, {   0x3fffe1, 22, }, {   0x7fffee, 23, }, {   0x7fffef, 23, },
64 	{    0xfffea, 20, }, {   0x3fffe2, 22, }, {   0x3fffe3, 22, }, {   0x3fffe4, 22, },
65 	{   0x7ffff0, 23, }, {   0x3fffe5, 22, }, {   0x3fffe6, 22, }, {   0x7ffff1, 23, },
66 	{  0x3ffffe0, 26, }, {  0x3ffffe1, 26, }, {    0xfffeb, 20, }, {    0x7fff1, 19, },
67 	{   0x3fffe7, 22, }, {   0x7ffff2, 23, }, {   0x3fffe8, 22, }, {  0x1ffffec, 25, },
68 	{  0x3ffffe2, 26, }, {  0x3ffffe3, 26, }, {  0x3ffffe4, 26, }, {  0x7ffffde, 27, },
69 	{  0x7ffffdf, 27, }, {  0x3ffffe5, 26, }, {   0xfffff1, 24, }, {  0x1ffffed, 25, },
70 	{    0x7fff2, 19, }, {   0x1fffe3, 21, }, {  0x3ffffe6, 26, }, {  0x7ffffe0, 27, },
71 	{  0x7ffffe1, 27, }, {  0x3ffffe7, 26, }, {  0x7ffffe2, 27, }, {   0xfffff2, 24, },
72 	{   0x1fffe4, 21, }, {   0x1fffe5, 21, }, {  0x3ffffe8, 26, }, {  0x3ffffe9, 26, },
73 	{  0xffffffd, 28, }, {  0x7ffffe3, 27, }, {  0x7ffffe4, 27, }, {  0x7ffffe5, 27, },
74 	{    0xfffec, 20, }, {   0xfffff3, 24, }, {    0xfffed, 20, }, {   0x1fffe6, 21, },
75 	{   0x3fffe9, 22, }, {   0x1fffe7, 21, }, {   0x1fffe8, 21, }, {   0x7ffff3, 23, },
76 	{   0x3fffea, 22, }, {   0x3fffeb, 22, }, {  0x1ffffee, 25, }, {  0x1ffffef, 25, },
77 	{   0xfffff4, 24, }, {   0xfffff5, 24, }, {  0x3ffffea, 26, }, {   0x7ffff4, 23, },
78 	{  0x3ffffeb, 26, }, {  0x7ffffe6, 27, }, {  0x3ffffec, 26, }, {  0x3ffffed, 26, },
79 	{  0x7ffffe7, 27, }, {  0x7ffffe8, 27, }, {  0x7ffffe9, 27, }, {  0x7ffffea, 27, },
80 	{  0x7ffffeb, 27, }, {  0xffffffe, 28, }, {  0x7ffffec, 27, }, {  0x7ffffed, 27, },
81 	{  0x7ffffee, 27, }, {  0x7ffffef, 27, }, {  0x7fffff0, 27, }, {  0x3ffffee, 26, },
82 };
83 
84 /* Prepare a MSB aligned Huffman code, with padding. */
test_huffman_code_prepare(uint32_t * buf,int index)85 static void test_huffman_code_prepare(uint32_t *buf, int index)
86 {
87 	uint8_t pad_len = 32 - test_huffman_codes[index].bitlen;
88 
89 	*buf = test_huffman_codes[index].code;
90 	/* Prepare buffer - align to MSB, add padding and covert to
91 	 * network byte order.
92 	 */
93 	*buf <<= pad_len;
94 	*buf |= (1UL << pad_len) - 1UL;
95 	*buf = htonl(*buf);
96 }
97 
ZTEST(http2_hpack,test_huffman_encode_single)98 ZTEST(http2_hpack, test_huffman_encode_single)
99 {
100 	ARRAY_FOR_EACH(test_huffman_codes, i) {
101 		uint8_t expected_len = DIV_ROUND_UP(test_huffman_codes[i].bitlen, 8);
102 		uint32_t expected;
103 		uint32_t buf = 0;
104 		uint8_t symbol = i;
105 		int ret;
106 
107 		test_huffman_code_prepare(&expected, i);
108 
109 		ret = http_hpack_huffman_encode(&symbol, 1, (uint8_t *)&buf, sizeof(buf));
110 		zassert_equal(ret, expected_len, "Wrong encoding length");
111 		zassert_mem_equal(&buf, &expected, expected_len,
112 				  "Symbol wrongly encoded");
113 	}
114 }
115 
ZTEST(http2_hpack,test_huffman_decode_single)116 ZTEST(http2_hpack, test_huffman_decode_single)
117 {
118 	ARRAY_FOR_EACH(test_huffman_codes, i) {
119 		uint8_t buflen = DIV_ROUND_UP(test_huffman_codes[i].bitlen, 8);
120 		uint32_t buf;
121 		uint8_t symbol;
122 		int ret;
123 
124 		test_huffman_code_prepare(&buf, i);
125 
126 		ret = http_hpack_huffman_decode((uint8_t *)&buf, buflen, &symbol, 1);
127 		zassert_equal(ret, 1, "Expected to decode 1 symbol");
128 		zassert_equal(symbol, i, "Wrong symbol decoded");
129 	}
130 }
131 
132 static uint8_t test_buf[600];
133 
ZTEST(http2_hpack,test_huffman_encode_decode_all)134 ZTEST(http2_hpack, test_huffman_encode_decode_all)
135 {
136 	uint8_t str[ARRAY_SIZE(test_huffman_codes)];
137 	int expected_len = 0;
138 	int ret;
139 
140 	ARRAY_FOR_EACH(str, i) {
141 		expected_len += test_huffman_codes[i].bitlen;
142 		str[i] = i;
143 	}
144 
145 	expected_len = DIV_ROUND_UP(expected_len, 8);
146 
147 	ret = http_hpack_huffman_encode(str, sizeof(str), test_buf, sizeof(test_buf));
148 	zassert_equal(ret, expected_len, "Wrong encoded length");
149 	memset(str, 0, sizeof(str));
150 	ret = http_hpack_huffman_decode(test_buf, expected_len, str, sizeof(str));
151 	zassert_equal(ret, sizeof(str), "Wrong decoded length");
152 
153 	ARRAY_FOR_EACH(str, i) {
154 		expected_len += test_huffman_codes[i].bitlen;
155 		zassert_equal(str[i], i, "Wrong symbol decoded");
156 	}
157 }
158 
159 struct example_huffman {
160 	const char *str;
161 	uint8_t encoded[46];
162 	uint8_t encoded_len;
163 };
164 
165 /* Encoding examples from RFC7541 */
166 static const struct example_huffman test_huffman[] = {
167 	{ "www.example.com",
168 	  { 0xf1, 0xe3, 0xc2, 0xe5, 0xf2, 0x3a, 0x6b, 0xa0,
169 	    0xab, 0x90, 0xf4, 0xff },
170 	  12 },
171 	{ "no-cache", { 0xa8, 0xeb, 0x10, 0x64, 0x9c, 0xbf }, 6 },
172 	{ "custom-key", { 0x25, 0xa8, 0x49, 0xe9, 0x5b, 0xa9, 0x7d, 0x7f }, 8 },
173 	{ "custom-value",
174 	  { 0x25, 0xa8, 0x49, 0xe9, 0x5b, 0xb8, 0xe8, 0xb4,
175 	    0xbf },
176 	  9 },
177 	{ "302", { 0x64, 0x02 }, 2 },
178 	{ "private", { 0xae, 0xc3, 0x77, 0x1a, 0x4b }, 5 },
179 	{ "Mon, 21 Oct 2013 20:13:21 GMT",
180 	  { 0xd0, 0x7a, 0xbe, 0x94, 0x10, 0x54, 0xd4, 0x44,
181 	    0xa8, 0x20, 0x05, 0x95, 0x04, 0x0b, 0x81, 0x66,
182 	    0xe0, 0x82, 0xa6, 0x2d, 0x1b, 0xff},
183 	  22 },
184 	{ "https://www.example.com",
185 	  { 0x9d, 0x29, 0xad, 0x17, 0x18, 0x63, 0xc7, 0x8f,
186 	    0x0b, 0x97, 0xc8, 0xe9, 0xae, 0x82, 0xae, 0x43,
187 	    0xd3},
188 	  17 },
189 	{ "307", { 0x64, 0x0e, 0xff }, 3 },
190 	{ "gzip", { 0x9b, 0xd9, 0xab }, 3 },
191 	{ "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
192 	  { 0x94, 0xe7, 0x82, 0x1d, 0xd7, 0xf2, 0xe6, 0xc7,
193 	    0xb3, 0x35, 0xdf, 0xdf, 0xcd, 0x5b, 0x39, 0x60,
194 	    0xd5, 0xaf, 0x27, 0x08, 0x7f, 0x36, 0x72, 0xc1,
195 	    0xab, 0x27, 0x0f, 0xb5, 0x29, 0x1f, 0x95, 0x87,
196 	    0x31, 0x60, 0x65, 0xc0, 0x03, 0xed, 0x4e, 0xe5,
197 	    0xb1, 0x06, 0x3d, 0x50, 0x07 },
198 	  45 },
199 };
200 
ZTEST(http2_hpack,test_huffman_encode_examples)201 ZTEST(http2_hpack, test_huffman_encode_examples)
202 {
203 	ARRAY_FOR_EACH(test_huffman, i) {
204 		int ret;
205 
206 		ret = http_hpack_huffman_encode(test_huffman[i].str,
207 						strlen(test_huffman[i].str),
208 						test_buf, sizeof(test_buf));
209 		zassert_equal(ret, test_huffman[i].encoded_len,
210 			      "Wrong encoding length");
211 		zassert_mem_equal(test_buf, test_huffman[i].encoded, ret,
212 				  "Symbol wrongly encoded");
213 	}
214 }
215 
ZTEST(http2_hpack,test_huffman_decode_examples)216 ZTEST(http2_hpack, test_huffman_decode_examples)
217 {
218 	ARRAY_FOR_EACH(test_huffman, i) {
219 		int ret;
220 
221 		ret = http_hpack_huffman_decode(test_huffman[i].encoded,
222 						test_huffman[i].encoded_len,
223 						test_buf, sizeof(test_buf));
224 		zassert_equal(ret, strlen(test_huffman[i].str),
225 			      "Wrong decoded length");
226 		zassert_mem_equal(test_buf, test_huffman[i].str, ret,
227 				  "Symbol wrongly encoded");
228 	}
229 }
230 
231 struct example_headers {
232 	const char *name;
233 	const char *value;
234 	uint8_t encoded[60];
235 	uint8_t encoded_len;
236 };
237 
238 /* Examples from RFC7541 */
239 static const struct example_headers test_static_headers[] = {
240 	{ ":method", "GET", { 0x82 }, 1 },
241 	{ ":scheme", "http", { 0x86 }, 1 },
242 	{ ":path", "/", { 0x84 }, 1 },
243 	{ ":scheme", "https", { 0x87 }, 1 },
244 	{ ":path", "/index.html", { 0x85 }, 1 },
245 	{ ":status", "200", { 0x88 }, 1 },
246 };
247 
test_hpack_verify_encode(const struct example_headers * example,size_t num_examples)248 static void test_hpack_verify_encode(const struct example_headers *example,
249 				     size_t num_examples)
250 {
251 	for (int i = 0; i < num_examples; i++) {
252 		struct http_hpack_header_buf hdr = {
253 			.name = example[i].name,
254 			.value = example[i].value,
255 			.name_len = strlen(example[i].name),
256 			.value_len = strlen(example[i].value)
257 		};
258 		int ret;
259 
260 		ret = http_hpack_encode_header(test_buf, sizeof(test_buf), &hdr);
261 		zassert_equal(ret, example[i].encoded_len, "Wrong encoding length");
262 		zassert_mem_equal(test_buf, example[i].encoded, ret,
263 				  "Header wrongly decoded");
264 	}
265 }
266 
test_hpack_verify_decode(const struct example_headers * example,size_t num_examples)267 static void test_hpack_verify_decode(const struct example_headers *example,
268 				     size_t num_examples)
269 {
270 	for (int i = 0; i < num_examples; i++) {
271 		struct http_hpack_header_buf hdr;
272 		int ret;
273 
274 		ret = http_hpack_decode_header(example[i].encoded, example[i].encoded_len, &hdr);
275 		zassert_equal(ret, example[i].encoded_len, "Wrong decoding length");
276 		zassert_equal(hdr.name_len, strlen(example[i].name),
277 			      "Wrong decoded header name length");
278 		zassert_equal(hdr.value_len, strlen(example[i].value),
279 			      "Wrong decoded header value length");
280 		zassert_mem_equal(hdr.name, example[i].name, hdr.name_len,
281 				  "Header name wrongly decoded");
282 		zassert_mem_equal(hdr.value, example[i].value, hdr.value_len,
283 				  "Header value wrongly decoded");
284 	}
285 }
286 
ZTEST(http2_hpack,test_http2_hpack_static_encode)287 ZTEST(http2_hpack, test_http2_hpack_static_encode)
288 {
289 	test_hpack_verify_encode(test_static_headers,
290 				 ARRAY_SIZE(test_static_headers));
291 }
292 
ZTEST(http2_hpack,test_http2_hpack_static_decode)293 ZTEST(http2_hpack, test_http2_hpack_static_decode)
294 {
295 	test_hpack_verify_decode(test_static_headers,
296 				 ARRAY_SIZE(test_static_headers));
297 }
298 
299 static const struct example_headers test_dec_literal_indexed_headers[] = {
300 	{ ":path", "/sample/path",
301 	  { 0x04, 0x0c, 0x2f, 0x73, 0x61, 0x6d, 0x70, 0x6c,
302 	    0x65, 0x2f, 0x70, 0x61, 0x74, 0x68 },
303 	  14 },
304 	{ ":authority", "www.example.com",
305 	  { 0x41, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78,
306 	    0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
307 	    0x6d },
308 	  17 },
309 	{ "cache-control", "no-cache",
310 	  { 0x58, 0x08, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63,
311 	    0x68, 0x65 },
312 	  10 },
313 	{ ":authority", "www.example.com", /* Huffman encoded */
314 	  { 0x41, 0x8c, 0xf1, 0xe3, 0xc2, 0xe5, 0xf2, 0x3a,
315 	    0x6b, 0xa0, 0xab, 0x90, 0xf4, 0xff },
316 	  14 },
317 	{ "cache-control", "no-cache", /* Huffman encoded */
318 	  { 0x58, 0x86, 0xa8, 0xeb, 0x10, 0x64, 0x9c, 0xbf },
319 	  8 },
320 	{ ":status", "302",
321 	  { 0x48, 0x03, 0x33, 0x30, 0x32 },
322 	  5 },
323 	{ "cache-control", "private",
324 	  { 0x58, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,
325 	    0x65 },
326 	  9 },
327 	{ "date", "Mon, 21 Oct 2013 20:13:21 GMT",
328 	  { 0x61, 0x1d, 0x4d, 0x6f, 0x6e, 0x2c, 0x20, 0x32,
329 	    0x31, 0x20, 0x4f, 0x63, 0x74, 0x20, 0x32, 0x30,
330 	    0x31, 0x33, 0x20, 0x32, 0x30, 0x3a, 0x31, 0x33,
331 	    0x3a, 0x32, 0x31, 0x20, 0x47, 0x4d, 0x54 },
332 	  31 },
333 	{ "location", "https://www.example.com",
334 	  { 0x6e, 0x17, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
335 	    0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78,
336 	    0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
337 	    0x6d },
338 	  25 },
339 	{ ":status", "307",
340 	  { 0x48, 0x03, 0x33, 0x30, 0x37 },
341 	  5 },
342 	{ "content-encoding", "gzip",
343 	  { 0x5a, 0x04, 0x67, 0x7a, 0x69, 0x70 },
344 	  6 },
345 	{ "set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
346 	  { 0x77, 0x38, 0x66, 0x6f, 0x6f, 0x3d, 0x41, 0x53,
347 	    0x44, 0x4a, 0x4b, 0x48, 0x51, 0x4b, 0x42, 0x5a,
348 	    0x58, 0x4f, 0x51, 0x57, 0x45, 0x4f, 0x50, 0x49,
349 	    0x55, 0x41, 0x58, 0x51, 0x57, 0x45, 0x4f, 0x49,
350 	    0x55, 0x3b, 0x20, 0x6d, 0x61, 0x78, 0x2d, 0x61,
351 	    0x67, 0x65, 0x3d, 0x33, 0x36, 0x30, 0x30, 0x3b,
352 	    0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
353 	    0x3d, 0x31 },
354 	  58 },
355 	{ ":status", "302", /* Huffman encoded */
356 	  { 0x48, 0x82, 0x64, 0x02 },
357 	  4 },
358 	{ "cache-control", "private", /* Huffman encoded */
359 	  { 0x58, 0x85, 0xae, 0xc3, 0x77, 0x1a, 0x4b },
360 	  7 },
361 	{ "date", "Mon, 21 Oct 2013 20:13:21 GMT", /* Huffman encoded */
362 	  { 0x61, 0x96, 0xd0, 0x7a, 0xbe, 0x94, 0x10, 0x54,
363 	    0xd4, 0x44, 0xa8, 0x20, 0x05, 0x95, 0x04, 0x0b,
364 	    0x81, 0x66, 0xe0, 0x82, 0xa6, 0x2d, 0x1b, 0xff },
365 	  24 },
366 	{ "location", "https://www.example.com", /* Huffman encoded */
367 	  { 0x6e, 0x91, 0x9d, 0x29, 0xad, 0x17, 0x18, 0x63,
368 	    0xc7, 0x8f, 0x0b, 0x97, 0xc8, 0xe9, 0xae, 0x82,
369 	    0xae, 0x43, 0xd3 },
370 	  19 },
371 	{ ":status", "307", /* Huffman encoded */
372 	  { 0x48, 0x83, 0x64, 0x0e, 0xff },
373 	  5 },
374 	{ "content-encoding", "gzip", /* Huffman encoded */
375 	  { 0x5a, 0x83, 0x9b, 0xd9, 0xab },
376 	  5 },
377 	{ "set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
378 	  /* Huffman encoded */
379 	  { 0x77, 0xad, 0x94, 0xe7, 0x82, 0x1d, 0xd7, 0xf2,
380 	    0xe6, 0xc7, 0xb3, 0x35, 0xdf, 0xdf, 0xcd, 0x5b,
381 	    0x39, 0x60, 0xd5, 0xaf, 0x27, 0x08, 0x7f, 0x36,
382 	    0x72, 0xc1, 0xab, 0x27, 0x0f, 0xb5, 0x29, 0x1f,
383 	    0x95, 0x87, 0x31, 0x60, 0x65, 0xc0, 0x03, 0xed,
384 	    0x4e, 0xe5, 0xb1, 0x06, 0x3d, 0x50, 0x07 },
385 	  47 },
386 };
387 
388 /* For encoding, we always use never indexed and Huffman when applicable. */
389 static const struct example_headers test_enc_literal_indexed_headers[] = {
390 	{ ":authority", "www.example.com", /* Huffman encoded */
391 	  { 0x11, 0x8c, 0xf1, 0xe3, 0xc2, 0xe5, 0xf2, 0x3a,
392 	    0x6b, 0xa0, 0xab, 0x90, 0xf4, 0xff },
393 	  14 },
394 	{ "cache-control", "no-cache", /* Huffman encoded */
395 	  { 0x1f, 0x09, 0x86, 0xa8, 0xeb, 0x10, 0x64, 0x9c, 0xbf },
396 	  9 },
397 	{ ":status", "302", /* Huffman encoded */
398 	  { 0x18, 0x82, 0x64, 0x02 },
399 	  4 },
400 	{ "cache-control", "private", /* Huffman encoded */
401 	  { 0x1f, 0x09, 0x85, 0xae, 0xc3, 0x77, 0x1a, 0x4b },
402 	  8 },
403 	{ "date", "Mon, 21 Oct 2013 20:13:21 GMT", /* Huffman encoded */
404 	  { 0x1f, 0x12, 0x96, 0xd0, 0x7a, 0xbe, 0x94, 0x10,
405 	    0x54, 0xd4, 0x44, 0xa8, 0x20, 0x05, 0x95, 0x04,
406 	    0x0b, 0x81, 0x66, 0xe0, 0x82, 0xa6, 0x2d, 0x1b,
407 	    0xff },
408 	  25 },
409 	{ "location", "https://www.example.com", /* Huffman encoded */
410 	  { 0x1f, 0x1f, 0x91, 0x9d, 0x29, 0xad, 0x17, 0x18,
411 	    0x63, 0xc7, 0x8f, 0x0b, 0x97, 0xc8, 0xe9, 0xae,
412 	    0x82, 0xae, 0x43, 0xd3 },
413 	  20 },
414 	{ ":status", "307",
415 	  /* In this case Huffman is not used, as it does not give any size savings. */
416 	  { 0x18, 0x03, 0x33, 0x30, 0x37 },
417 	  5 },
418 	{ "content-encoding", "gzip", /* Huffman encoded */
419 	  { 0x1f, 0x0b, 0x83, 0x9b, 0xd9, 0xab },
420 	  6 },
421 	{ "set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
422 	  /* Huffman encoded */
423 	  { 0x1f, 0x28, 0xad, 0x94, 0xe7, 0x82, 0x1d, 0xd7,
424 	    0xf2, 0xe6, 0xc7, 0xb3, 0x35, 0xdf, 0xdf, 0xcd,
425 	    0x5b, 0x39, 0x60, 0xd5, 0xaf, 0x27, 0x08, 0x7f,
426 	    0x36, 0x72, 0xc1, 0xab, 0x27, 0x0f, 0xb5, 0x29,
427 	    0x1f, 0x95, 0x87, 0x31, 0x60, 0x65, 0xc0, 0x03,
428 	    0xed, 0x4e, 0xe5, 0xb1, 0x06, 0x3d, 0x50, 0x07 },
429 	  48 },
430 };
431 
ZTEST(http2_hpack,test_http2_hpack_literal_indexed_encode)432 ZTEST(http2_hpack, test_http2_hpack_literal_indexed_encode)
433 {
434 	test_hpack_verify_encode(test_enc_literal_indexed_headers,
435 				 ARRAY_SIZE(test_enc_literal_indexed_headers));
436 }
437 
ZTEST(http2_hpack,test_http2_hpack_literal_indexed_decode)438 ZTEST(http2_hpack, test_http2_hpack_literal_indexed_decode)
439 {
440 	test_hpack_verify_decode(test_dec_literal_indexed_headers,
441 				 ARRAY_SIZE(test_dec_literal_indexed_headers));
442 	/* We should be able to decode encoding test cases as well. */
443 	test_hpack_verify_decode(test_enc_literal_indexed_headers,
444 				 ARRAY_SIZE(test_enc_literal_indexed_headers));
445 }
446 
447 static const struct example_headers test_dec_literal_not_indexed_headers[] = {
448 	{ "custom-key", "custom-header",
449 	  { 0x40, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d,
450 	    0x2d, 0x6b, 0x65, 0x79, 0x0d, 0x63, 0x75, 0x73,
451 	    0x74, 0x6f, 0x6d, 0x2d, 0x68, 0x65, 0x61, 0x64,
452 	    0x65, 0x72 },
453 	  26 },
454 	{ "password", "secret",
455 	  { 0x10, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
456 	    0x72, 0x64, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65,
457 	    0x74 },
458 	  17 },
459 	{ "custom-key", "custom-value",
460 	  { 0x40, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d,
461 	    0x2d, 0x6b, 0x65, 0x79, 0x0c, 0x63, 0x75, 0x73,
462 	    0x74, 0x6f, 0x6d, 0x2d, 0x76, 0x61, 0x6c, 0x75,
463 	    0x65 },
464 	  25 },
465 	{ "custom-key", "custom-value", /* Huffman encoded */
466 	  { 0x40, 0x88, 0x25, 0xa8, 0x49, 0xe9, 0x5b, 0xa9,
467 	    0x7d, 0x7f, 0x89, 0x25, 0xa8, 0x49, 0xe9, 0x5b,
468 	    0xb8, 0xe8, 0xb4, 0xbf },
469 	  20 },
470 };
471 
472 /* For encoding, we always use never indexed and Huffman. */
473 static const struct example_headers test_enc_literal_not_indexed_headers[] = {
474 	{ "custom-key", "custom-value", /* Huffman encoded */
475 	  { 0x10, 0x88, 0x25, 0xa8, 0x49, 0xe9, 0x5b, 0xa9,
476 	    0x7d, 0x7f, 0x89, 0x25, 0xa8, 0x49, 0xe9, 0x5b,
477 	    0xb8, 0xe8, 0xb4, 0xbf },
478 	  20 },
479 };
480 
481 /* For encoding, we always use never indexed and Huffman codes. */
ZTEST(http2_hpack,test_http2_hpack_literal_not_indexed_encode)482 ZTEST(http2_hpack, test_http2_hpack_literal_not_indexed_encode)
483 {
484 	test_hpack_verify_encode(test_enc_literal_not_indexed_headers,
485 				 ARRAY_SIZE(test_enc_literal_not_indexed_headers));
486 }
487 
ZTEST(http2_hpack,test_http2_hpack_literal_not_indexed_decode)488 ZTEST(http2_hpack, test_http2_hpack_literal_not_indexed_decode)
489 {
490 	test_hpack_verify_decode(test_dec_literal_not_indexed_headers,
491 				 ARRAY_SIZE(test_dec_literal_not_indexed_headers));
492 	/* We should be able to decode encoding test cases as well. */
493 	test_hpack_verify_decode(test_enc_literal_not_indexed_headers,
494 				 ARRAY_SIZE(test_enc_literal_not_indexed_headers));
495 }
496 
497 ZTEST_SUITE(http2_hpack, NULL, NULL, NULL, NULL, NULL);
498