chacha20 poly1305 + increment_iv
Karel Miko
6 years ago
35 | 35 | Newz(0, RETVAL, 1, struct chacha20poly1305_struct); |
36 | 36 | if (!RETVAL) croak("FATAL: Newz failed"); |
37 | 37 | Copy(&self->state, &RETVAL->state, 1, struct chacha20poly1305_struct); |
38 | OUTPUT: | |
39 | RETVAL | |
40 | ||
41 | int | |
42 | increment_iv(Crypt::AuthEnc::ChaCha20Poly1305 self) | |
43 | CODE: | |
44 | { | |
45 | int rv; | |
46 | rv = chacha20poly1305_inciv(&self->state); | |
47 | if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_inciv failed: %s", error_to_string(rv)); | |
48 | RETVAL = rv; | |
49 | } | |
38 | 50 | OUTPUT: |
39 | 51 | RETVAL |
40 | 52 |
81 | 81 | |
82 | 82 | =head1 DESCRIPTION |
83 | 83 | |
84 | Galois/Counter Mode (ChaCha20Poly1305) - provides encryption and authentication. | |
84 | Provides encryption and authentication based on ChaCha20 + Poly1305 as defined in RFC 7539 - L<https://tools.ietf.org/html/rfc7539> | |
85 | 85 | |
86 | 86 | =head1 EXPORT |
87 | 87 | |
144 | 144 | |
145 | 145 | my $ae_new = $ae->clone; |
146 | 146 | |
147 | =head2 increment_iv | |
148 | ||
149 | $ae->increment_iv; | |
150 | ||
147 | 151 | =head1 SEE ALSO |
148 | 152 | |
149 | 153 | =over |
8 | 8 | ltc/encauth/chachapoly/chacha20poly1305_done.o ltc/encauth/chachapoly/chacha20poly1305_encrypt.o \ |
9 | 9 | ltc/encauth/chachapoly/chacha20poly1305_init.o ltc/encauth/chachapoly/chacha20poly1305_memory.o \ |
10 | 10 | ltc/encauth/chachapoly/chacha20poly1305_setiv.o ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \ |
11 | ltc/encauth/chachapoly/chacha20poly1305_inciv.o \ | |
11 | 12 | ltc/encauth/ccm/ccm_add_aad.o ltc/encauth/ccm/ccm_add_nonce.o ltc/encauth/ccm/ccm_done.o ltc/encauth/ccm/ccm_init.o \ |
12 | 13 | ltc/encauth/ccm/ccm_memory.o ltc/encauth/ccm/ccm_process.o ltc/encauth/ccm/ccm_reset.o \ |
13 | 14 | ltc/encauth/eax/eax_addheader.o ltc/encauth/eax/eax_decrypt.o ltc/encauth/eax/eax_decrypt_verify_memory.o \ |
8 | 8 | ltc/encauth/chachapoly/chacha20poly1305_done.obj ltc/encauth/chachapoly/chacha20poly1305_encrypt.obj \ |
9 | 9 | ltc/encauth/chachapoly/chacha20poly1305_init.obj ltc/encauth/chachapoly/chacha20poly1305_memory.obj \ |
10 | 10 | ltc/encauth/chachapoly/chacha20poly1305_setiv.obj ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.obj \ |
11 | ltc/encauth/chachapoly/chacha20poly1305_inciv.obj \ | |
11 | 12 | ltc/encauth/ccm/ccm_add_aad.obj ltc/encauth/ccm/ccm_add_nonce.obj ltc/encauth/ccm/ccm_done.obj ltc/encauth/ccm/ccm_init.obj \ |
12 | 13 | ltc/encauth/ccm/ccm_memory.obj ltc/encauth/ccm/ccm_process.obj ltc/encauth/ccm/ccm_reset.obj \ |
13 | 14 | ltc/encauth/eax/eax_addheader.obj ltc/encauth/eax/eax_decrypt.obj ltc/encauth/eax/eax_decrypt_verify_memory.obj \ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Reset ChaCha20Poly1305 state with incremented IV - used by https://shadowsocks.org/en/spec/AEAD-Ciphers.html | |
15 | @param st The ChaCha20Poly1305 state | |
16 | @param iv The IV data to add | |
17 | @param inlen The length of the IV (must be 12 or 8) | |
18 | @return CRYPT_OK on success | |
19 | */ | |
20 | int chacha20poly1305_inciv(chacha20poly1305_state *st) | |
21 | { | |
22 | int err; | |
23 | unsigned char tmp_iv[12]; | |
24 | unsigned long ivlen; | |
25 | ||
26 | LTC_ARGCHK(st != NULL); | |
27 | ||
28 | ivlen = st->chacha.ivlen; | |
29 | if (ivlen == 12) { | |
30 | STORE32L(st->chacha.input[13], tmp_iv + 0); | |
31 | STORE32L(st->chacha.input[14], tmp_iv + 4); | |
32 | STORE32L(st->chacha.input[15], tmp_iv + 8); | |
33 | /* increment IV 96bit / 12 bytes */ | |
34 | if (!++tmp_iv[0] && !++tmp_iv[1] && !++tmp_iv[2] && !++tmp_iv[3] && | |
35 | !++tmp_iv[4] && !++tmp_iv[5] && !++tmp_iv[6] && !++tmp_iv[7] && | |
36 | !++tmp_iv[8] && !++tmp_iv[9] && !++tmp_iv[10] && !++tmp_iv[11]) | |
37 | { | |
38 | err = CRYPT_ERROR; /* IV overflow */ | |
39 | } | |
40 | else { | |
41 | err = chacha20poly1305_setiv(st, tmp_iv, 12); | |
42 | } | |
43 | } | |
44 | else if (ivlen == 8) { | |
45 | STORE32L(st->chacha.input[14], tmp_iv + 0); | |
46 | STORE32L(st->chacha.input[15], tmp_iv + 4); | |
47 | /* increment IV 64bit / 8 bytes */ | |
48 | if (!++tmp_iv[0] && !++tmp_iv[1] && !++tmp_iv[2] && !++tmp_iv[3] && | |
49 | !++tmp_iv[4] && !++tmp_iv[5] && !++tmp_iv[6] && !++tmp_iv[7]) | |
50 | { | |
51 | err = CRYPT_ERROR; /* IV overflow */ | |
52 | } | |
53 | else { | |
54 | err = chacha20poly1305_setiv(st, tmp_iv, 8); | |
55 | } | |
56 | } | |
57 | else { | |
58 | err = CRYPT_ERROR; /* invalid IV length */ | |
59 | } | |
60 | ||
61 | return err; | |
62 | } | |
63 | ||
64 | #endif |