1 2 #define TEST_NAME "aead_chacha20poly1305" 3 #include "cmptest.h" 4 5 static int 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 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 366 main(void) 367 { 368 tv(); 369 tv_ietf(); 370 371 return 0; 372 } 373