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