1 2 #define TEST_NAME "secretstream" 3 #include "cmptest.h" 4 5 int 6 main(void) 7 { 8 crypto_secretstream_xchacha20poly1305_state *state, *statesave; 9 crypto_secretstream_xchacha20poly1305_state state_copy; 10 unsigned char *ad; 11 unsigned char *header; 12 unsigned char *k; 13 unsigned char *c1, *c2, *c3, *csave; 14 unsigned char *m1, *m2, *m3; 15 unsigned char *m1_, *m2_, *m3_; 16 unsigned long long res_len; 17 size_t ad_len; 18 size_t m1_len, m2_len, m3_len; 19 int ret; 20 unsigned char tag; 21 22 state = (crypto_secretstream_xchacha20poly1305_state *) 23 sodium_malloc(crypto_secretstream_xchacha20poly1305_statebytes()); 24 statesave = (crypto_secretstream_xchacha20poly1305_state *) 25 sodium_malloc(crypto_secretstream_xchacha20poly1305_statebytes()); 26 header = (unsigned char *) 27 sodium_malloc(crypto_secretstream_xchacha20poly1305_HEADERBYTES); 28 29 ad_len = randombytes_uniform(100); 30 m1_len = randombytes_uniform(1000); 31 m2_len = randombytes_uniform(1000); 32 m3_len = randombytes_uniform(1000); 33 34 c1 = (unsigned char *) 35 sodium_malloc(m1_len + crypto_secretstream_xchacha20poly1305_ABYTES); 36 c2 = (unsigned char *) 37 sodium_malloc(m2_len + crypto_secretstream_xchacha20poly1305_ABYTES); 38 c3 = (unsigned char *) 39 sodium_malloc(m3_len + crypto_secretstream_xchacha20poly1305_ABYTES); 40 csave = (unsigned char *) 41 sodium_malloc((m1_len | m2_len | m3_len) + crypto_secretstream_xchacha20poly1305_ABYTES); 42 43 ad = (unsigned char *) sodium_malloc(ad_len); 44 m1 = (unsigned char *) sodium_malloc(m1_len); 45 m2 = (unsigned char *) sodium_malloc(m2_len); 46 m3 = (unsigned char *) sodium_malloc(m3_len); 47 m1_ = (unsigned char *) sodium_malloc(m1_len); 48 m2_ = (unsigned char *) sodium_malloc(m2_len); 49 m3_ = (unsigned char *) sodium_malloc(m3_len); 50 51 randombytes_buf(ad, ad_len); 52 53 randombytes_buf(m1, m1_len); 54 memcpy(m1_, m1, m1_len); 55 randombytes_buf(m2, m2_len); 56 memcpy(m2_, m2, m2_len); 57 randombytes_buf(m3, m3_len); 58 memcpy(m3_, m3, m3_len); 59 60 k = (unsigned char *) 61 sodium_malloc(crypto_secretstream_xchacha20poly1305_KEYBYTES); 62 crypto_secretstream_xchacha20poly1305_keygen(k); 63 64 /* push */ 65 66 ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); 67 assert(ret == 0); 68 69 ret = crypto_secretstream_xchacha20poly1305_push 70 (state, c1, &res_len, m1, m1_len, NULL, 0, 0); 71 assert(ret == 0); 72 assert(res_len == m1_len + crypto_secretstream_xchacha20poly1305_ABYTES); 73 74 ret = crypto_secretstream_xchacha20poly1305_push 75 (state, c2, NULL, m2, m2_len, ad, 0, 0); 76 assert(ret == 0); 77 78 ret = crypto_secretstream_xchacha20poly1305_push 79 (state, c3, NULL, m3, m3_len, ad, ad_len, 80 crypto_secretstream_xchacha20poly1305_TAG_FINAL); 81 assert(ret == 0); 82 83 /* pull */ 84 85 ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); 86 assert(ret == 0); 87 88 ret = crypto_secretstream_xchacha20poly1305_pull 89 (state, m1, &res_len, &tag, 90 c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 91 assert(ret == 0); 92 assert(tag == 0); 93 assert(memcmp(m1, m1_, m1_len) == 0); 94 assert(res_len == m1_len); 95 96 ret = crypto_secretstream_xchacha20poly1305_pull 97 (state, m2, NULL, &tag, 98 c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 99 assert(ret == 0); 100 assert(tag == 0); 101 assert(memcmp(m2, m2_, m2_len) == 0); 102 103 if (ad_len > 0) { 104 ret = crypto_secretstream_xchacha20poly1305_pull 105 (state, m3, NULL, &tag, 106 c3, m3_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 107 assert(ret == -1); 108 } 109 ret = crypto_secretstream_xchacha20poly1305_pull 110 (state, m3, NULL, &tag, 111 c3, m3_len + crypto_secretstream_xchacha20poly1305_ABYTES, ad, ad_len); 112 assert(ret == 0); 113 assert(tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL); 114 assert(memcmp(m3, m3_, m3_len) == 0); 115 116 /* previous with FINAL tag */ 117 118 ret = crypto_secretstream_xchacha20poly1305_pull 119 (state, m3, NULL, &tag, 120 c3, m3_len + crypto_secretstream_xchacha20poly1305_ABYTES, ad, ad_len); 121 assert(ret == -1); 122 123 /* previous without a tag */ 124 125 ret = crypto_secretstream_xchacha20poly1305_pull 126 (state, m2, NULL, &tag, 127 c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 128 assert(ret == -1); 129 130 /* short ciphertext */ 131 132 ret = crypto_secretstream_xchacha20poly1305_pull 133 (state, m2, NULL, &tag, c2, 134 randombytes_uniform(crypto_secretstream_xchacha20poly1305_ABYTES), 135 NULL, 0); 136 assert(ret == -1); 137 ret = crypto_secretstream_xchacha20poly1305_pull 138 (state, m2, NULL, &tag, c2, 0, NULL, 0); 139 assert(ret == -1); 140 141 /* empty ciphertext */ 142 143 ret = crypto_secretstream_xchacha20poly1305_pull 144 (state, m2, NULL, &tag, c2, 145 crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 146 assert(ret == -1); 147 148 /* without explicit rekeying */ 149 150 ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); 151 assert(ret == 0); 152 ret = crypto_secretstream_xchacha20poly1305_push 153 (state, c1, NULL, m1, m1_len, NULL, 0, 0); 154 assert(ret == 0); 155 ret = crypto_secretstream_xchacha20poly1305_push 156 (state, c2, NULL, m2, m2_len, NULL, 0, 0); 157 assert(ret == 0); 158 159 ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); 160 assert(ret == 0); 161 ret = crypto_secretstream_xchacha20poly1305_pull 162 (state, m1, NULL, &tag, 163 c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 164 assert(ret == 0); 165 ret = crypto_secretstream_xchacha20poly1305_pull 166 (state, m2, NULL, &tag, 167 c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 168 assert(ret == 0); 169 170 /* with explicit rekeying */ 171 172 ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); 173 assert(ret == 0); 174 ret = crypto_secretstream_xchacha20poly1305_push 175 (state, c1, NULL, m1, m1_len, NULL, 0, 0); 176 assert(ret == 0); 177 178 crypto_secretstream_xchacha20poly1305_rekey(state); 179 180 ret = crypto_secretstream_xchacha20poly1305_push 181 (state, c2, NULL, m2, m2_len, NULL, 0, 0); 182 assert(ret == 0); 183 184 ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); 185 assert(ret == 0); 186 ret = crypto_secretstream_xchacha20poly1305_pull 187 (state, m1, NULL, &tag, 188 c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 189 assert(ret == 0); 190 191 ret = crypto_secretstream_xchacha20poly1305_pull 192 (state, m2, NULL, &tag, 193 c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 194 assert(ret == -1); 195 196 crypto_secretstream_xchacha20poly1305_rekey(state); 197 198 ret = crypto_secretstream_xchacha20poly1305_pull 199 (state, m2, NULL, &tag, 200 c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 201 assert(ret == 0); 202 203 /* with explicit rekeying using TAG_REKEY */ 204 205 ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); 206 assert(ret == 0); 207 208 memcpy(statesave, state, sizeof *state); 209 210 ret = crypto_secretstream_xchacha20poly1305_push 211 (state, c1, NULL, m1, m1_len, NULL, 0, crypto_secretstream_xchacha20poly1305_TAG_REKEY); 212 assert(ret == 0); 213 214 ret = crypto_secretstream_xchacha20poly1305_push 215 (state, c2, NULL, m2, m2_len, NULL, 0, 0); 216 assert(ret == 0); 217 218 memcpy(csave, c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES); 219 220 ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); 221 assert(ret == 0); 222 ret = crypto_secretstream_xchacha20poly1305_pull 223 (state, m1, NULL, &tag, 224 c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, &tag, 0); 225 assert(ret == 0); 226 assert(tag == crypto_secretstream_xchacha20poly1305_TAG_REKEY); 227 228 ret = crypto_secretstream_xchacha20poly1305_pull 229 (state, m2, NULL, &tag, 230 c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, &tag, 0); 231 assert(ret == 0); 232 assert(tag == 0); 233 234 memcpy(state, statesave, sizeof *state); 235 236 ret = crypto_secretstream_xchacha20poly1305_push 237 (state, c1, NULL, m1, m1_len, NULL, 0, 0); 238 assert(ret == 0); 239 240 ret = crypto_secretstream_xchacha20poly1305_push 241 (state, c2, NULL, m2, m2_len, NULL, 0, 0); 242 assert(ret == 0); 243 244 assert(memcmp(csave, c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES) != 0); 245 246 /* New stream */ 247 248 ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); 249 assert(ret == 0); 250 251 ret = crypto_secretstream_xchacha20poly1305_push 252 (state, c1, &res_len, m1, m1_len, NULL, 0, 253 crypto_secretstream_xchacha20poly1305_TAG_PUSH); 254 assert(ret == 0); 255 assert(res_len == m1_len + crypto_secretstream_xchacha20poly1305_ABYTES); 256 257 /* Force a counter overflow, check that the key has been updated 258 * even though the tag was not changed to REKEY */ 259 260 memset(state->nonce, 0xff, 4U); 261 state_copy = *state; 262 263 ret = crypto_secretstream_xchacha20poly1305_push 264 (state, c2, NULL, m2, m2_len, ad, 0, 0); 265 assert(ret == 0); 266 267 assert(memcmp(state_copy.k, state->k, sizeof state->k) != 0); 268 assert(memcmp(state_copy.nonce, state->nonce, sizeof state->nonce) != 0); 269 assert(state->nonce[0] == 1U); 270 assert(sodium_is_zero(state->nonce + 1, 3U)); 271 272 ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); 273 assert(ret == 0); 274 275 ret = crypto_secretstream_xchacha20poly1305_pull 276 (state, m1, &res_len, &tag, 277 c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 278 assert(ret == 0); 279 assert(tag == crypto_secretstream_xchacha20poly1305_TAG_PUSH); 280 assert(memcmp(m1, m1_, m1_len) == 0); 281 assert(res_len == m1_len); 282 283 memset(state->nonce, 0xff, 4U); 284 285 ret = crypto_secretstream_xchacha20poly1305_pull 286 (state, m2, NULL, &tag, 287 c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); 288 assert(ret == 0); 289 assert(tag == 0); 290 assert(memcmp(m2, m2_, m2_len) == 0); 291 292 sodium_free(m3_); 293 sodium_free(m2_); 294 sodium_free(m1_); 295 sodium_free(m3); 296 sodium_free(m2); 297 sodium_free(m1); 298 sodium_free(ad); 299 sodium_free(csave); 300 sodium_free(c3); 301 sodium_free(c2); 302 sodium_free(c1); 303 sodium_free(k); 304 sodium_free(header); 305 sodium_free(statesave); 306 sodium_free(state); 307 308 assert(crypto_secretstream_xchacha20poly1305_abytes() == 309 crypto_secretstream_xchacha20poly1305_ABYTES); 310 assert(crypto_secretstream_xchacha20poly1305_headerbytes() == 311 crypto_secretstream_xchacha20poly1305_HEADERBYTES); 312 assert(crypto_secretstream_xchacha20poly1305_keybytes() == 313 crypto_secretstream_xchacha20poly1305_KEYBYTES); 314 assert(crypto_secretstream_xchacha20poly1305_messagebytes_max() == 315 crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX); 316 317 assert(crypto_secretstream_xchacha20poly1305_tag_message() == 318 crypto_secretstream_xchacha20poly1305_TAG_MESSAGE); 319 assert(crypto_secretstream_xchacha20poly1305_tag_push() == 320 crypto_secretstream_xchacha20poly1305_TAG_PUSH); 321 assert(crypto_secretstream_xchacha20poly1305_tag_rekey() == 322 crypto_secretstream_xchacha20poly1305_TAG_REKEY); 323 assert(crypto_secretstream_xchacha20poly1305_tag_final() == 324 crypto_secretstream_xchacha20poly1305_TAG_FINAL); 325 326 printf("OK\n"); 327 328 return 0; 329 } 330