1 
2 #define TEST_NAME "aead_xchacha20poly1305"
3 #include "cmptest.h"
4 
5 static int
6 tv(void)
7 {
8 #undef  MLEN
9 #define MLEN 114U
10 #undef  ADLEN
11 #define ADLEN 12U
12 #undef  CLEN
13 #define CLEN (MLEN + crypto_aead_xchacha20poly1305_ietf_ABYTES)
14     static const unsigned char firstkey[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]
15         = {
16             0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
17             0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
18             0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
19             0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
20         };
21 #undef  MESSAGE
22 #define MESSAGE "Ladies and Gentlemen of the class of '99: If I could offer you " \
23     "only one tip for the future, sunscreen would be it."
24     unsigned char *m = (unsigned char *) sodium_malloc(MLEN);
25     static const unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES]
26         = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
27             0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53 };
28     static const unsigned char ad[ADLEN]
29         = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 };
30     unsigned char *c = (unsigned char *) sodium_malloc(CLEN);
31     unsigned char *detached_c = (unsigned char *) sodium_malloc(MLEN);
32     unsigned char *key2 = (unsigned char *) sodium_malloc(crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
33     unsigned char *mac = (unsigned char *) sodium_malloc(crypto_aead_xchacha20poly1305_ietf_ABYTES);
34     unsigned char *m2 = (unsigned char *) sodium_malloc(MLEN);
35     unsigned long long found_clen;
36     unsigned long long found_maclen;
37     unsigned long long m2len;
38     size_t i;
39 
40     assert(sizeof MESSAGE - 1U == MLEN);
41     memcpy(m, MESSAGE, MLEN);
42     crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN,
43                                                ad, ADLEN,
44                                                NULL, nonce, firstkey);
45     if (found_clen != MLEN + crypto_aead_xchacha20poly1305_ietf_abytes()) {
46         printf("found_clen is not properly set\n");
47     }
48     for (i = 0U; i < CLEN; ++i) {
49         printf(",0x%02x", (unsigned int) c[i]);
50         if (i % 8 == 7) {
51             printf("\n");
52         }
53     }
54     printf("\n");
55     crypto_aead_xchacha20poly1305_ietf_encrypt_detached(detached_c,
56                                                         mac, &found_maclen,
57                                                         m, MLEN,
58                                                         ad, ADLEN,
59                                                         NULL, nonce, firstkey);
60     if (found_maclen != crypto_aead_xchacha20poly1305_ietf_abytes()) {
61         printf("found_maclen is not properly set\n");
62     }
63     if (memcmp(detached_c, c, MLEN) != 0) {
64         printf("detached ciphertext is bogus\n");
65     }
66 
67     if (crypto_aead_xchacha20poly1305_ietf_decrypt(NULL, 0, NULL, c, CLEN, ad,
68                                                    ADLEN, nonce, firstkey) != 0) {
69         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() tag-only verification failed\n");
70     }
71     if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN, ad,
72                                                    ADLEN, nonce, firstkey) != 0) {
73         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed\n");
74     }
75     if (m2len != MLEN) {
76         printf("m2len is not properly set\n");
77     }
78     if (memcmp(m, m2, MLEN) != 0) {
79         printf("m != m2\n");
80     }
81     memset(m2, 0, m2len);
82     if (crypto_aead_xchacha20poly1305_ietf_decrypt_detached(m2, NULL,
83                                                             c, MLEN, mac,
84                                                             ad, ADLEN,
85                                                             nonce, firstkey) != 0) {
86         printf("crypto_aead_xchacha20poly1305_ietf_decrypt_detached() failed\n");
87     }
88     if (memcmp(m, m2, MLEN) != 0) {
89         printf("detached m != m2\n");
90     }
91 
92     for (i = 0U; i < CLEN; i++) {
93         c[i] ^= (i + 1U);
94         if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, NULL, NULL, c, CLEN,
95                                                        ad, ADLEN, nonce, firstkey)
96             == 0 || memcmp(m, m2, MLEN) == 0) {
97             printf("message can be forged\n");
98         }
99         c[i] ^= (i + 1U);
100     }
101     crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN,
102                                                NULL, 0U, NULL, nonce, firstkey);
103     if (found_clen != CLEN) {
104         printf("clen is not properly set (adlen=0)\n");
105     }
106     for (i = 0U; i < CLEN; ++i) {
107         printf(",0x%02x", (unsigned int) c[i]);
108         if (i % 8 == 7) {
109             printf("\n");
110         }
111     }
112     printf("\n");
113     if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN,
114                                                    NULL, 0U, nonce, firstkey) != 0) {
115         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
116     }
117     if (m2len != MLEN) {
118         printf("m2len is not properly set (adlen=0)\n");
119     }
120     if (memcmp(m, m2, MLEN) != 0) {
121         printf("m != m2 (adlen=0)\n");
122     }
123     m2len = 1;
124     if (crypto_aead_xchacha20poly1305_ietf_decrypt(
125             m2, &m2len, NULL, guard_page,
126             randombytes_uniform(crypto_aead_xchacha20poly1305_ietf_ABYTES),
127             NULL, 0U, nonce, firstkey) != -1) {
128         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() worked with a short "
129                "ciphertext\n");
130     }
131     if (m2len != 0) {
132         printf("Message length should have been set to zero after a failure\n");
133     }
134     m2len = 1;
135     if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U,
136                                                   nonce, firstkey) != -1) {
137         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() worked with an empty "
138                "ciphertext\n");
139     }
140     if (m2len != 0) {
141         printf("Message length should have been set to zero after a failure\n");
142     }
143 
144     memcpy(c, m, MLEN);
145     crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, c, MLEN,
146                                                NULL, 0U, NULL, nonce, firstkey);
147     if (found_clen != CLEN) {
148         printf("clen is not properly set (adlen=0)\n");
149     }
150     for (i = 0U; i < CLEN; ++i) {
151         printf(",0x%02x", (unsigned int) c[i]);
152         if (i % 8 == 7) {
153             printf("\n");
154         }
155     }
156     printf("\n");
157 
158     if (crypto_aead_xchacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN,
159                                                    NULL, 0U, nonce, firstkey) != 0) {
160         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
161     }
162     if (m2len != MLEN) {
163         printf("m2len is not properly set (adlen=0)\n");
164     }
165     if (memcmp(m, c, MLEN) != 0) {
166         printf("m != c (adlen=0)\n");
167     }
168 
169     crypto_aead_xchacha20poly1305_ietf_keygen(key2);
170     if (crypto_aead_xchacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN,
171                                                    NULL, 0U, nonce, key2) == 0) {
172         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() with a wrong key should have failed\n");
173     }
174 
175     sodium_free(c);
176     sodium_free(detached_c);
177     sodium_free(key2);
178     sodium_free(mac);
179     sodium_free(m2);
180     sodium_free(m);
181 
182     assert(crypto_aead_xchacha20poly1305_ietf_abytes() == crypto_aead_xchacha20poly1305_ietf_ABYTES);
183     assert(crypto_aead_xchacha20poly1305_ietf_keybytes() == crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
184     assert(crypto_aead_xchacha20poly1305_ietf_npubbytes() == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
185     assert(crypto_aead_xchacha20poly1305_ietf_nsecbytes() == 0U);
186     assert(crypto_aead_xchacha20poly1305_ietf_nsecbytes() == crypto_aead_xchacha20poly1305_ietf_NSECBYTES);
187     assert(crypto_aead_xchacha20poly1305_ietf_messagebytes_max() == crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX);
188     assert(crypto_aead_xchacha20poly1305_IETF_KEYBYTES  == crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
189     assert(crypto_aead_xchacha20poly1305_IETF_NSECBYTES == crypto_aead_xchacha20poly1305_ietf_NSECBYTES);
190     assert(crypto_aead_xchacha20poly1305_IETF_NPUBBYTES == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
191     assert(crypto_aead_xchacha20poly1305_IETF_ABYTES    == crypto_aead_xchacha20poly1305_ietf_ABYTES);
192     assert(crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX == crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX);
193 
194     return 0;
195 }
196 
197 int
198 main(void)
199 {
200     tv();
201 
202     return 0;
203 }
204