blob: 34551f8404783d374a4992ae477c715bb9081c63 [file] [log] [blame]
Damjan Marion003330c2023-04-12 12:19:05 +00001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2023 Cisco Systems, Inc.
3 */
4
5#include <vppinfra/format.h>
6#include <vppinfra/test/test.h>
7#include <vppinfra/crypto/poly1305.h>
8
9static const u8 text1[375] = {
10 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
11 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, 0x54, 0x46,
12 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20,
13 0x74, 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
14 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
15 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20,
16 0x6f, 0x72, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e,
17 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
18 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x52, 0x46,
19 0x43, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, 0x74, 0x61,
20 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77,
21 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e,
22 0x74, 0x65, 0x78, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45,
23 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x20, 0x69,
24 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20,
25 0x61, 0x6e, 0x20, 0x22, 0x49, 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
26 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2e, 0x20, 0x53, 0x75,
27 0x63, 0x68, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73,
28 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c,
29 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69,
30 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
31 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61,
32 0x73, 0x20, 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64,
33 0x20, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
34 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
35 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20,
36 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65,
37 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61,
38 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
39};
40
41const static struct
42{
43 char *name;
44 u32 len;
45 const u8 key[32];
46 const u8 *msg;
47 const u8 out[16];
48} test_cases[] = {
49 {
50 .name = "test1",
51 .len = 34,
52 .out = { 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, 0xc2, 0x2b, 0x8b,
53 0xaf, 0x0c, 0x01, 0x27, 0xa9 },
54 .key = { 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, 0x7f, 0x44, 0x52,
55 0xfe, 0x42, 0xd5, 0x06, 0xa8, 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d,
56 0xb2, 0xfd, 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b },
57 .msg = (u8[34]){ 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, 0x61,
58 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f, 0x72, 0x75,
59 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63,
60 0x68, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70 },
61 },
62 {
63 .name = "RFC8439 A3 TV1",
64 .len = 64,
65 .out = {},
66 .key = {},
67 .msg = (u8[64]){},
68 },
69 {
70 .name = "RFC8439 A3 TV2",
71 .len = sizeof (text1),
72 .out = { 0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70, 0xf0, 0xef, 0xca,
73 0x96, 0x22, 0x7a, 0x86, 0x3e },
74 .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0,
76 0x60, 0x70, 0xf0, 0xef, 0xca, 0x96, 0x22, 0x7a, 0x86, 0x3e },
77 .msg = text1,
78 },
79 {
80 .name = "RFC8439 A3 TV3",
81 .len = sizeof (text1),
82 .out = { 0xf3, 0x47, 0x7e, 0x7c, 0xd9, 0x54, 0x17, 0xaf, 0x89, 0xa6, 0xb8,
83 0x79, 0x4c, 0x31, 0x0c, 0xf0
84
85 },
86 .key = { 0x36, 0xe5, 0xf6, 0xb5, 0xc5, 0xe0, 0x60, 0x70, 0xf0, 0xef, 0xca,
87 0x96, 0x22, 0x7a, 0x86, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
89
90 .msg = text1,
91 },
92 {
93 .name = "RFC8439 A3 TV4",
94 .len = 127,
95 .key = { 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, 0xf3, 0x33, 0x88,
96 0x86, 0x04, 0xf6, 0xb5, 0xf0, 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b,
97 0x80, 0x09, 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0 },
98 .msg =
99 (u8[127]){
100 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x69,
101 0x67, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
102 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, 0x76, 0x65, 0x73, 0x0a,
103 0x44, 0x69, 0x64, 0x20, 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
104 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74,
105 0x68, 0x65, 0x20, 0x77, 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
106 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20,
107 0x74, 0x68, 0x65, 0x20, 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
108 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d,
109 0x6f, 0x6d, 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
110 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e },
111 .out = { 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, 0xe7, 0x08, 0xdc,
112 0x7c, 0xbc, 0xc5, 0xeb, 0x62 },
113 },
114 {
115 /* Test Vector #5:
116 * If one uses 130-bit partial reduction, does the code handle the case
117 * where partially reduced final result is not fully reduced? */
118 .name = "RFC8439 A3 TV5",
119 .len = 16,
120 .key = { 2 },
121 .msg = (u8[16]){ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
123 .out = { 3 },
124 },
125 {
126 /* Test Vector #6:
127 * What happens if addition of s overflows modulo 2^128? */
128 .name = "RFC8439 A3 TV6",
129 .len = 16,
130 .key = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
133 .msg = (u8[16]){ 2 },
134 .out = { 3 },
135 },
136 {
137 /* Test Vector #7:
138 * What happens if data limb is all ones and there is carry from lower
139 * limb? */
140 .name = "RFC8439 A3 TV7",
141 .len = 48,
142 .key = { 1 },
143 .msg =
144 (u8[48]){ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff,
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
147 0xff, 0xff, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
149 .out = { 5 },
150 },
151 {
152 /* Test Vector #8:
153 * What happens if final result from polynomial part is exactly 2^130-5? */
154 .name = "RFC8439 A3 TV8",
155 .len = 48,
156 .key = { 1 },
157 .msg =
158 (u8[48]){ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfe, 0xfe, 0xfe,
160 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
161 0xfe, 0xfe, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
162 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
163 .out = { 0 },
164 },
165 {
166 /* Test Vector #9:
167 * What happens if final result from polynomial part is exactly 2^130-6? */
168 .name = "RFC8439 A3 TV9",
169 .len = 16,
170 .key = { 2 },
171 .msg = (u8[16]){ 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
172 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
173 .out = { 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
174 0xff, 0xff, 0xff, 0xff, 0xff },
175 },
176 {
177 /* Test Vector #10:
178 * What happens if 5*H+L-type reduction produces 131-bit intermediate
179 * result? */
180 .name = "RFC8439 A3 TV10",
181 .len = 64,
182 .key = { [0] = 1, [8] = 4 },
183 .msg =
184 (u8[64]){ 0xE3, 0x35, 0x94, 0xD7, 0x50, 0x5E, 0x43, 0xB9, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x94, 0xD7, 0x50,
186 0x5E, 0x43, 0x79, 0xCD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00 },
191 .out = { 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00 },
193 },
194 {
195 /* Test Vector #11:
196 * What happens if 5*H+L-type reduction produces 131-bit final result? */
197 .name = "RFC8439 A3 TV11",
198 .len = 48,
199 .key = { [0] = 1, [8] = 4 },
200 .msg =
201 (u8[48]){ 0xE3, 0x35, 0x94, 0xD7, 0x50, 0x5E, 0x43, 0xB9, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x94, 0xD7, 0x50,
203 0x5E, 0x43, 0x79, 0xCD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
206 .out = { 0x13 },
207 }
208};
209
210static clib_error_t *
211test_clib_poly1305 (clib_error_t *err)
212{
213 u8 out[16] = {};
214
215 FOREACH_ARRAY_ELT (tc, test_cases)
216 {
217 clib_poly1305 (tc->key, tc->msg, tc->len, out);
218 if (memcmp (out, tc->out, 16) != 0)
219 err = clib_error_return (
220 err,
221 "\ntest: %s"
222 "\nkey: %U"
223 "\ndata: %U"
224 "\nexp out: %U"
225 "\ncalc out: %U\n",
226 tc->name, format_hexdump, tc->key, 32, format_hexdump, tc->msg,
227 tc->len, format_hexdump, tc->out, 16, format_hexdump, out, 16);
228 }
229 return err;
230}
231
232void __test_perf_fn
233perftest_64byte (test_perf_t *tp)
234{
235 u32 n = tp->n_ops;
236 u8 *m = test_mem_alloc_and_fill_inc_u8 (n * 64, 0, 0);
237 u8 *k = test_mem_alloc_and_fill_inc_u8 (n * 32, 0, 0);
238 u8 *t = test_mem_alloc (n * 16);
239
240 test_perf_event_enable (tp);
241 for (int i = 0; i < n; i++, t += 16, k += 32, m += 64)
242 clib_poly1305 (k, m, 64, t);
243 test_perf_event_disable (tp);
244}
245
246void __test_perf_fn
247perftest_byte (test_perf_t *tp)
248{
249 u32 n = tp->n_ops;
250
251 u8 *m = test_mem_alloc_and_fill_inc_u8 (n, 0, 0);
252 u8 *k = test_mem_alloc_and_fill_inc_u8 (32, 0, 0);
253 u8 *t = test_mem_alloc (16);
254
255 test_perf_event_enable (tp);
256 clib_poly1305 (k, m, n, t);
257 test_perf_event_disable (tp);
258}
259
260REGISTER_TEST (clib_poly1305) = {
261 .name = "clib_poly1305",
262 .fn = test_clib_poly1305,
263 .perf_tests = PERF_TESTS (
264 { .name = "fixed size (64 bytes)", .n_ops = 1024, .fn = perftest_64byte },
265 { .name = "variable size (per byte)",
266 .n_ops = 16384,
267 .fn = perftest_byte }),
268};