1717from __future__ import absolute_import , division , print_function , \
1818 with_statement
1919
20- from ctypes import c_char_p , c_int , c_ulonglong , byref , \
20+ from ctypes import c_char_p , c_int , c_ulonglong , byref , c_ulong , \
2121 create_string_buffer , c_void_p
2222
2323from shadowsocks .crypto import util
2929
3030buf_size = 2048
3131
32- # for salsa20 and chacha20
32+ # for salsa20 and chacha20 and chacha20-ietf
3333BLOCK_SIZE = 64
3434
3535
@@ -51,6 +51,13 @@ def load_libsodium():
5151 c_ulonglong ,
5252 c_char_p , c_ulonglong ,
5353 c_char_p )
54+ libsodium .crypto_stream_chacha20_ietf_xor_ic .restype = c_int
55+ libsodium .crypto_stream_chacha20_ietf_xor_ic .argtypes = (c_void_p ,
56+ c_char_p ,
57+ c_ulonglong ,
58+ c_char_p ,
59+ c_ulong ,
60+ c_char_p )
5461
5562 buf = create_string_buffer (buf_size )
5663 loaded = True
@@ -68,6 +75,8 @@ def __init__(self, cipher_name, key, iv, op):
6875 self .cipher = libsodium .crypto_stream_salsa20_xor_ic
6976 elif cipher_name == 'chacha20' :
7077 self .cipher = libsodium .crypto_stream_chacha20_xor_ic
78+ elif cipher_name == 'chacha20-ietf' :
79+ self .cipher = libsodium .crypto_stream_chacha20_ietf_xor_ic
7180 else :
7281 raise Exception ('Unknown cipher' )
7382 # byte counter, not block counter
@@ -97,6 +106,7 @@ def update(self, data):
97106ciphers = {
98107 'salsa20' : (32 , 8 , SodiumCrypto ),
99108 'chacha20' : (32 , 8 , SodiumCrypto ),
109+ 'chacha20-ietf' : (32 , 12 , SodiumCrypto ),
100110}
101111
102112
@@ -115,6 +125,15 @@ def test_chacha20():
115125 util .run_cipher (cipher , decipher )
116126
117127
128+ def test_chacha20_ietf ():
129+
130+ cipher = SodiumCrypto ('chacha20-ietf' , b'k' * 32 , b'i' * 16 , 1 )
131+ decipher = SodiumCrypto ('chacha20-ietf' , b'k' * 32 , b'i' * 16 , 0 )
132+
133+ util .run_cipher (cipher , decipher )
134+
135+
118136if __name__ == '__main__' :
119137 test_chacha20 ()
120138 test_salsa20 ()
139+ test_chacha20_ietf ()
0 commit comments