Home | History | Annotate | Line # | Download | only in default
      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