1 
2 #define TEST_NAME "aead_chacha20poly1305"
3 #include "cmptest.h"
4 
5 static int
tv(void)6 tv(void)
7 {
8 #undef  MLEN
9 #define MLEN 10U
10 #undef  ADLEN
11 #define ADLEN 10U
12 #undef  CLEN
13 #define CLEN (MLEN + crypto_aead_chacha20poly1305_ABYTES)
14     static const unsigned char firstkey[crypto_aead_chacha20poly1305_KEYBYTES]
15         = { 0x42, 0x90, 0xbc, 0xb1, 0x54, 0x17, 0x35, 0x31, 0xf3, 0x14, 0xaf,
16             0x57, 0xf3, 0xbe, 0x3b, 0x50, 0x06, 0xda, 0x37, 0x1e, 0xce, 0x27,
17             0x2a, 0xfa, 0x1b, 0x5d, 0xbd, 0xd1, 0x10, 0x0a, 0x10, 0x07 };
18     static const unsigned char m[MLEN]
19         = { 0x86, 0xd0, 0x99, 0x74, 0x84, 0x0b, 0xde, 0xd2, 0xa5, 0xca };
20     static const unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES]
21         = { 0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a };
22     static const unsigned char ad[ADLEN]
23         = { 0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0 };
24     unsigned char *c = (unsigned char *) sodium_malloc(CLEN);
25     unsigned char *detached_c = (unsigned char *) sodium_malloc(MLEN);
26     unsigned char *mac = (unsigned char *) sodium_malloc(crypto_aead_chacha20poly1305_ABYTES);
27     unsigned char *m2 = (unsigned char *) sodium_malloc(MLEN);
28     unsigned long long found_clen;
29     unsigned long long found_maclen;
30     unsigned long long m2len;
31     size_t i;
32 
33     crypto_aead_chacha20poly1305_encrypt(c, &found_clen, m, MLEN,
34                                          ad, ADLEN,
35                                          NULL, nonce, firstkey);
36     if (found_clen != CLEN) {
37         printf("found_clen is not properly set\n");
38     }
39     for (i = 0U; i < CLEN; ++i) {
40         printf(",0x%02x", (unsigned int) c[i]);
41         if (i % 8 == 7) {
42             printf("\n");
43         }
44     }
45     printf("\n");
46     crypto_aead_chacha20poly1305_encrypt_detached(detached_c,
47                                                   mac, &found_maclen,
48                                                   m, MLEN, ad, ADLEN,
49                                                   NULL, nonce, firstkey);
50     if (found_maclen != crypto_aead_chacha20poly1305_abytes()) {
51         printf("found_maclen is not properly set\n");
52     }
53     if (memcmp(detached_c, c, MLEN) != 0) {
54         printf("detached ciphertext is bogus\n");
55     }
56 
57     if (crypto_aead_chacha20poly1305_decrypt(m2, &m2len, NULL, c, CLEN,
58                                              ad, ADLEN,
59                                              nonce, firstkey) != 0) {
60         printf("crypto_aead_chacha20poly1305_decrypt() failed\n");
61     }
62     if (m2len != MLEN) {
63         printf("m2len is not properly set\n");
64     }
65     if (memcmp(m, m2, MLEN) != 0) {
66         printf("m != m2\n");
67     }
68     memset(m2, 0, m2len);
69     assert(crypto_aead_chacha20poly1305_decrypt_detached(NULL, NULL,
70                                                          c, MLEN, mac,
71                                                          ad, ADLEN,
72                                                          nonce, firstkey) == 0);
73     if (crypto_aead_chacha20poly1305_decrypt_detached(m2, NULL,
74                                                       c, MLEN, mac,
75                                                       ad, ADLEN,
76                                                       nonce, firstkey) != 0) {
77         printf("crypto_aead_chacha20poly1305_decrypt_detached() failed\n");
78     }
79     if (memcmp(m, m2, MLEN) != 0) {
80         printf("detached m != m2\n");
81     }
82 
83     for (i = 0U; i < CLEN; i++) {
84         c[i] ^= (i + 1U);
85         if (crypto_aead_chacha20poly1305_decrypt(m2, NULL, NULL, c, CLEN,
86                                                  ad, ADLEN, nonce, firstkey)
87             == 0 || memcmp(m, m2, MLEN) == 0) {
88             printf("message can be forged\n");
89         }
90         c[i] ^= (i + 1U);
91     }
92 
93     crypto_aead_chacha20poly1305_encrypt(c, &found_clen, m, MLEN,
94                                          NULL, 0U, NULL, nonce, firstkey);
95     if (found_clen != CLEN) {
96         printf("found_clen is not properly set (adlen=0)\n");
97     }
98     for (i = 0U; i < CLEN; ++i) {
99         printf(",0x%02x", (unsigned int) c[i]);
100         if (i % 8 == 7) {
101             printf("\n");
102         }
103     }
104     printf("\n");
105 
106     if (crypto_aead_chacha20poly1305_decrypt(m2, &m2len, NULL, c, CLEN,
107                                              NULL, 0U, nonce, firstkey) != 0) {
108         printf("crypto_aead_chacha20poly1305_decrypt() failed (adlen=0)\n");
109     }
110     if (m2len != MLEN) {
111         printf("m2len is not properly set (adlen=0)\n");
112     }
113     if (memcmp(m, m2, MLEN) != 0) {
114         printf("m != m2 (adlen=0)\n");
115     }
116     m2len = 1;
117     if (crypto_aead_chacha20poly1305_decrypt(
118             m2, &m2len, NULL, NULL,
119             randombytes_uniform(crypto_aead_chacha20poly1305_ABYTES),
120             NULL, 0U, nonce, firstkey) != -1) {
121         printf("crypto_aead_chacha20poly1305_decrypt() worked with a short "
122                "ciphertext\n");
123     }
124     if (m2len != 0) {
125         printf("Message length should have been set to zero after a failure\n");
126     }
127     m2len = 1;
128     if (crypto_aead_chacha20poly1305_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U,
129                                              nonce, firstkey) != -1) {
130         printf("crypto_aead_chacha20poly1305_decrypt() worked with an empty "
131                "ciphertext\n");
132     }
133     if (m2len != 0) {
134         printf("Message length should have been set to zero after a failure\n");
135     }
136 
137     memcpy(c, m, MLEN);
138     crypto_aead_chacha20poly1305_encrypt(c, &found_clen, c, MLEN,
139                                          NULL, 0U, NULL, nonce, firstkey);
140     if (found_clen != CLEN) {
141         printf("found_clen is not properly set (adlen=0)\n");
142     }
143     for (i = 0U; i < CLEN; ++i) {
144         printf(",0x%02x", (unsigned int) c[i]);
145         if (i % 8 == 7) {
146             printf("\n");
147         }
148     }
149     printf("\n");
150 
151     if (crypto_aead_chacha20poly1305_decrypt(c, &m2len, NULL, c, CLEN,
152                                              NULL, 0U, nonce, firstkey) != 0) {
153         printf("crypto_aead_chacha20poly1305_decrypt() failed (adlen=0)\n");
154     }
155     if (m2len != MLEN) {
156         printf("m2len is not properly set (adlen=0)\n");
157     }
158     if (memcmp(m, c, MLEN) != 0) {
159         printf("m != c (adlen=0)\n");
160     }
161 
162     sodium_free(c);
163     sodium_free(detached_c);
164     sodium_free(mac);
165     sodium_free(m2);
166 
167     assert(crypto_aead_chacha20poly1305_keybytes() > 0U);
168     assert(crypto_aead_chacha20poly1305_npubbytes() > 0U);
169     assert(crypto_aead_chacha20poly1305_nsecbytes() == 0U);
170     assert(crypto_aead_chacha20poly1305_messagebytes_max() > 0U);
171     assert(crypto_aead_chacha20poly1305_messagebytes_max() == crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX);
172     assert(crypto_aead_chacha20poly1305_keybytes() == crypto_aead_chacha20poly1305_KEYBYTES);
173     assert(crypto_aead_chacha20poly1305_nsecbytes() == crypto_aead_chacha20poly1305_NSECBYTES);
174     assert(crypto_aead_chacha20poly1305_npubbytes() == crypto_aead_chacha20poly1305_NPUBBYTES);
175     assert(crypto_aead_chacha20poly1305_abytes() == crypto_aead_chacha20poly1305_ABYTES);
176 
177     return 0;
178 }
179 
180 static int
tv_ietf(void)181 tv_ietf(void)
182 {
183 #undef  MLEN
184 #define MLEN 114U
185 #undef  ADLEN
186 #define ADLEN 12U
187 #undef  CLEN
188 #define CLEN (MLEN + crypto_aead_chacha20poly1305_ietf_ABYTES)
189     static const unsigned char firstkey[crypto_aead_chacha20poly1305_ietf_KEYBYTES]
190         = {
191             0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
192             0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
193             0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
194             0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
195         };
196 #undef  MESSAGE
197 #define MESSAGE "Ladies and Gentlemen of the class of '99: If I could offer you " \
198 "only one tip for the future, sunscreen would be it."
199     unsigned char *m = (unsigned char *) sodium_malloc(MLEN);
200     static const unsigned char nonce[crypto_aead_chacha20poly1305_ietf_NPUBBYTES]
201         = { 0x07, 0x00, 0x00, 0x00,
202             0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 };
203     static const unsigned char ad[ADLEN]
204         = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 };
205     unsigned char *c = (unsigned char *) sodium_malloc(CLEN);
206     unsigned char *detached_c = (unsigned char *) sodium_malloc(MLEN);
207     unsigned char *mac = (unsigned char *) sodium_malloc(crypto_aead_chacha20poly1305_ietf_ABYTES);
208     unsigned char *m2 = (unsigned char *) sodium_malloc(MLEN);
209     unsigned long long found_clen;
210     unsigned long long found_maclen;
211     unsigned long long m2len;
212     size_t i;
213 
214     assert(sizeof MESSAGE - 1U == MLEN);
215     memcpy(m, MESSAGE, MLEN);
216     crypto_aead_chacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN,
217                                               ad, ADLEN,
218                                               NULL, nonce, firstkey);
219     if (found_clen != MLEN + crypto_aead_chacha20poly1305_ietf_abytes()) {
220         printf("found_clen is not properly set\n");
221     }
222     for (i = 0U; i < CLEN; ++i) {
223         printf(",0x%02x", (unsigned int) c[i]);
224         if (i % 8 == 7) {
225             printf("\n");
226         }
227     }
228     printf("\n");
229     crypto_aead_chacha20poly1305_ietf_encrypt_detached(detached_c,
230                                                        mac, &found_maclen,
231                                                        m, MLEN,
232                                                        ad, ADLEN,
233                                                        NULL, nonce, firstkey);
234     if (found_maclen != crypto_aead_chacha20poly1305_ietf_abytes()) {
235         printf("found_maclen is not properly set\n");
236     }
237     if (memcmp(detached_c, c, MLEN) != 0) {
238         printf("detached ciphertext is bogus\n");
239     }
240 
241     if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN, ad,
242                                                   ADLEN, nonce, firstkey) != 0) {
243         printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed\n");
244     }
245     if (m2len != MLEN) {
246         printf("m2len is not properly set\n");
247     }
248     if (memcmp(m, m2, MLEN) != 0) {
249         printf("m != m2\n");
250     }
251     memset(m2, 0, m2len);
252     assert(crypto_aead_chacha20poly1305_ietf_decrypt_detached(NULL, NULL,
253                                                               c, MLEN, mac,
254                                                               ad, ADLEN,
255                                                               nonce, firstkey) == 0);
256     if (crypto_aead_chacha20poly1305_ietf_decrypt_detached(m2, NULL,
257                                                            c, MLEN, mac,
258                                                            ad, ADLEN,
259                                                            nonce, firstkey) != 0) {
260         printf("crypto_aead_chacha20poly1305_ietf_decrypt_detached() failed\n");
261     }
262     if (memcmp(m, m2, MLEN) != 0) {
263         printf("detached m != m2\n");
264     }
265 
266     for (i = 0U; i < CLEN; i++) {
267         c[i] ^= (i + 1U);
268         if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, NULL, NULL, c, CLEN,
269                                                       ad, ADLEN, nonce, firstkey)
270             == 0 || memcmp(m, m2, MLEN) == 0) {
271             printf("message can be forged\n");
272         }
273         c[i] ^= (i + 1U);
274     }
275     crypto_aead_chacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN,
276                                               NULL, 0U, NULL, nonce, firstkey);
277     if (found_clen != CLEN) {
278         printf("clen is not properly set (adlen=0)\n");
279     }
280     for (i = 0U; i < CLEN; ++i) {
281         printf(",0x%02x", (unsigned int) c[i]);
282         if (i % 8 == 7) {
283             printf("\n");
284         }
285     }
286     printf("\n");
287     if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN,
288                                                   NULL, 0U, nonce, firstkey) != 0) {
289         printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
290     }
291     if (m2len != MLEN) {
292         printf("m2len is not properly set (adlen=0)\n");
293     }
294     if (memcmp(m, m2, MLEN) != 0) {
295         printf("m != m2 (adlen=0)\n");
296     }
297     m2len = 1;
298     if (crypto_aead_chacha20poly1305_ietf_decrypt(
299             m2, &m2len, NULL, NULL,
300             randombytes_uniform(crypto_aead_chacha20poly1305_ietf_ABYTES),
301             NULL, 0U, nonce, firstkey) != -1) {
302         printf("crypto_aead_chacha20poly1305_ietf_decrypt() worked with a short "
303                "ciphertext\n");
304     }
305     if (m2len != 0) {
306         printf("Message length should have been set to zero after a failure\n");
307     }
308     m2len = 1;
309     if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U,
310                                                   nonce, firstkey) != -1) {
311         printf("crypto_aead_chacha20poly1305_ietf_decrypt() worked with an empty "
312                "ciphertext\n");
313     }
314     if (m2len != 0) {
315         printf("Message length should have been set to zero after a failure\n");
316     }
317 
318     memcpy(c, m, MLEN);
319     crypto_aead_chacha20poly1305_ietf_encrypt(c, &found_clen, c, MLEN,
320                                               NULL, 0U, NULL, nonce, firstkey);
321     if (found_clen != CLEN) {
322         printf("clen is not properly set (adlen=0)\n");
323     }
324     for (i = 0U; i < CLEN; ++i) {
325         printf(",0x%02x", (unsigned int) c[i]);
326         if (i % 8 == 7) {
327             printf("\n");
328         }
329     }
330     printf("\n");
331 
332     if (crypto_aead_chacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN,
333                                                   NULL, 0U, nonce, firstkey) != 0) {
334         printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
335     }
336     if (m2len != MLEN) {
337         printf("m2len is not properly set (adlen=0)\n");
338     }
339     if (memcmp(m, c, MLEN) != 0) {
340         printf("m != c (adlen=0)\n");
341     }
342 
343     sodium_free(c);
344     sodium_free(detached_c);
345     sodium_free(mac);
346     sodium_free(m2);
347     sodium_free(m);
348 
349     assert(crypto_aead_chacha20poly1305_ietf_keybytes() > 0U);
350     assert(crypto_aead_chacha20poly1305_ietf_keybytes() == crypto_aead_chacha20poly1305_keybytes());
351     assert(crypto_aead_chacha20poly1305_ietf_npubbytes() > 0U);
352     assert(crypto_aead_chacha20poly1305_ietf_npubbytes() > crypto_aead_chacha20poly1305_npubbytes());
353     assert(crypto_aead_chacha20poly1305_ietf_nsecbytes() == 0U);
354     assert(crypto_aead_chacha20poly1305_ietf_nsecbytes() == crypto_aead_chacha20poly1305_nsecbytes());
355     assert(crypto_aead_chacha20poly1305_ietf_messagebytes_max() == crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX);
356     assert(crypto_aead_chacha20poly1305_IETF_KEYBYTES  == crypto_aead_chacha20poly1305_ietf_KEYBYTES);
357     assert(crypto_aead_chacha20poly1305_IETF_NSECBYTES == crypto_aead_chacha20poly1305_ietf_NSECBYTES);
358     assert(crypto_aead_chacha20poly1305_IETF_NPUBBYTES == crypto_aead_chacha20poly1305_ietf_NPUBBYTES);
359     assert(crypto_aead_chacha20poly1305_IETF_ABYTES    == crypto_aead_chacha20poly1305_ietf_ABYTES);
360     assert(crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX == crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX);
361 
362     return 0;
363 }
364 
365 int
main(void)366 main(void)
367 {
368     tv();
369     tv_ietf();
370 
371     return 0;
372 }
373