1 
2 #define TEST_NAME "aead_xchacha20poly1305"
3 #include "cmptest.h"
4 
5 static int
tv(void)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 };
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(m2, &m2len, NULL, c, CLEN, ad,
68                                                    ADLEN, nonce, firstkey) != 0) {
69         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed\n");
70     }
71     if (m2len != MLEN) {
72         printf("m2len is not properly set\n");
73     }
74     if (memcmp(m, m2, MLEN) != 0) {
75         printf("m != m2\n");
76     }
77     memset(m2, 0, m2len);
78     if (crypto_aead_xchacha20poly1305_ietf_decrypt_detached(m2, NULL,
79                                                             c, MLEN, mac,
80                                                             ad, ADLEN,
81                                                             nonce, firstkey) != 0) {
82         printf("crypto_aead_xchacha20poly1305_ietf_decrypt_detached() failed\n");
83     }
84     if (memcmp(m, m2, MLEN) != 0) {
85         printf("detached m != m2\n");
86     }
87 
88     for (i = 0U; i < CLEN; i++) {
89         c[i] ^= (i + 1U);
90         if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, NULL, NULL, c, CLEN,
91                                                        ad, ADLEN, nonce, firstkey)
92             == 0 || memcmp(m, m2, MLEN) == 0) {
93             printf("message can be forged\n");
94         }
95         c[i] ^= (i + 1U);
96     }
97     crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN,
98                                                NULL, 0U, NULL, nonce, firstkey);
99     if (found_clen != CLEN) {
100         printf("clen is not properly set (adlen=0)\n");
101     }
102     for (i = 0U; i < CLEN; ++i) {
103         printf(",0x%02x", (unsigned int) c[i]);
104         if (i % 8 == 7) {
105             printf("\n");
106         }
107     }
108     printf("\n");
109     if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN,
110                                                    NULL, 0U, nonce, firstkey) != 0) {
111         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
112     }
113     if (m2len != MLEN) {
114         printf("m2len is not properly set (adlen=0)\n");
115     }
116     if (memcmp(m, m2, MLEN) != 0) {
117         printf("m != m2 (adlen=0)\n");
118     }
119     m2len = 1;
120     if (crypto_aead_xchacha20poly1305_ietf_decrypt(
121             m2, &m2len, NULL, NULL,
122             randombytes_uniform(crypto_aead_xchacha20poly1305_ietf_ABYTES),
123             NULL, 0U, nonce, firstkey) != -1) {
124         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() worked with a short "
125                "ciphertext\n");
126     }
127     if (m2len != 0) {
128         printf("Message length should have been set to zero after a failure\n");
129     }
130     m2len = 1;
131     if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U,
132                                                   nonce, firstkey) != -1) {
133         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() worked with an empty "
134                "ciphertext\n");
135     }
136     if (m2len != 0) {
137         printf("Message length should have been set to zero after a failure\n");
138     }
139 
140     memcpy(c, m, MLEN);
141     crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, c, MLEN,
142                                                NULL, 0U, NULL, nonce, firstkey);
143     if (found_clen != CLEN) {
144         printf("clen is not properly set (adlen=0)\n");
145     }
146     for (i = 0U; i < CLEN; ++i) {
147         printf(",0x%02x", (unsigned int) c[i]);
148         if (i % 8 == 7) {
149             printf("\n");
150         }
151     }
152     printf("\n");
153 
154     if (crypto_aead_xchacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN,
155                                                    NULL, 0U, nonce, firstkey) != 0) {
156         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
157     }
158     if (m2len != MLEN) {
159         printf("m2len is not properly set (adlen=0)\n");
160     }
161     if (memcmp(m, c, MLEN) != 0) {
162         printf("m != c (adlen=0)\n");
163     }
164 
165     crypto_aead_xchacha20poly1305_ietf_keygen(key2);
166     if (crypto_aead_xchacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN,
167                                                    NULL, 0U, nonce, key2) == 0) {
168         printf("crypto_aead_xchacha20poly1305_ietf_decrypt() with a wrong key should have failed\n");
169     }
170 
171     sodium_free(c);
172     sodium_free(detached_c);
173     sodium_free(key2);
174     sodium_free(mac);
175     sodium_free(m2);
176     sodium_free(m);
177 
178     assert(crypto_aead_xchacha20poly1305_ietf_abytes() == crypto_aead_xchacha20poly1305_ietf_ABYTES);
179     assert(crypto_aead_xchacha20poly1305_ietf_keybytes() == crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
180     assert(crypto_aead_xchacha20poly1305_ietf_npubbytes() == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
181     assert(crypto_aead_xchacha20poly1305_ietf_nsecbytes() == 0U);
182     assert(crypto_aead_xchacha20poly1305_ietf_nsecbytes() == crypto_aead_xchacha20poly1305_ietf_NSECBYTES);
183     assert(crypto_aead_xchacha20poly1305_ietf_messagebytes_max() == crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX);
184     assert(crypto_aead_xchacha20poly1305_IETF_KEYBYTES  == crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
185     assert(crypto_aead_xchacha20poly1305_IETF_NSECBYTES == crypto_aead_xchacha20poly1305_ietf_NSECBYTES);
186     assert(crypto_aead_xchacha20poly1305_IETF_NPUBBYTES == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
187     assert(crypto_aead_xchacha20poly1305_IETF_ABYTES    == crypto_aead_xchacha20poly1305_ietf_ABYTES);
188     assert(crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX == crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX);
189 
190     return 0;
191 }
192 
193 int
main(void)194 main(void)
195 {
196     tv();
197 
198     return 0;
199 }
200