3 # Allow direct execution
8 sys
.path
.insert(0, os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
))))
13 from yt_dlp
.aes
import (
16 aes_cbc_decrypt_bytes
,
25 aes_gcm_decrypt_and_verify
,
26 aes_gcm_decrypt_and_verify_bytes
,
28 from yt_dlp
.dependencies
import Cryptodome_AES
29 from yt_dlp
.utils
import bytes_to_intlist
, intlist_to_bytes
31 # the encrypted data can be generate with 'devscripts/generate_aes_testdata.py'
34 class TestAES(unittest
.TestCase
):
36 self
.key
= self
.iv
= [0x20, 0x15] + 14 * [0]
37 self
.secret_msg
= b
'Secret message goes here'
39 def test_encrypt(self
):
42 encrypted
= aes_encrypt(bytes_to_intlist(msg
), key
)
43 decrypted
= intlist_to_bytes(aes_decrypt(encrypted
, key
))
44 self
.assertEqual(decrypted
, msg
)
46 def test_cbc_decrypt(self
):
47 data
= b
'\x97\x92+\xe5\x0b\xc3\x18\x91ky9m&\xb3\xb5@\xe6\x27\xc2\x96.\xc8u\x88\xab9-[\x9e|\xf1\xcd'
48 decrypted
= intlist_to_bytes(aes_cbc_decrypt(bytes_to_intlist(data
), self
.key
, self
.iv
))
49 self
.assertEqual(decrypted
.rstrip(b
'\x08'), self
.secret_msg
)
51 decrypted
= aes_cbc_decrypt_bytes(data
, intlist_to_bytes(self
.key
), intlist_to_bytes(self
.iv
))
52 self
.assertEqual(decrypted
.rstrip(b
'\x08'), self
.secret_msg
)
54 def test_cbc_encrypt(self
):
55 data
= bytes_to_intlist(self
.secret_msg
)
56 encrypted
= intlist_to_bytes(aes_cbc_encrypt(data
, self
.key
, self
.iv
))
59 b
'\x97\x92+\xe5\x0b\xc3\x18\x91ky9m&\xb3\xb5@\xe6\'\xc2\x96.\xc8u\x88\xab9-[\x9e|\xf1\xcd')
61 def test_ctr_decrypt(self
):
62 data
= bytes_to_intlist(b
'\x03\xc7\xdd\xd4\x8e\xb3\xbc\x1a*O\xdc1\x12+8Aio\xd1z\xb5#\xaf\x08')
63 decrypted
= intlist_to_bytes(aes_ctr_decrypt(data
, self
.key
, self
.iv
))
64 self
.assertEqual(decrypted
.rstrip(b
'\x08'), self
.secret_msg
)
66 def test_ctr_encrypt(self
):
67 data
= bytes_to_intlist(self
.secret_msg
)
68 encrypted
= intlist_to_bytes(aes_ctr_encrypt(data
, self
.key
, self
.iv
))
71 b
'\x03\xc7\xdd\xd4\x8e\xb3\xbc\x1a*O\xdc1\x12+8Aio\xd1z\xb5#\xaf\x08')
73 def test_gcm_decrypt(self
):
74 data
= b
'\x159Y\xcf5eud\x90\x9c\x85&]\x14\x1d\x0f.\x08\xb4T\xe4/\x17\xbd'
75 authentication_tag
= b
'\xe8&I\x80rI\x07\x9d}YWuU@:e'
77 decrypted
= intlist_to_bytes(aes_gcm_decrypt_and_verify(
78 bytes_to_intlist(data
), self
.key
, bytes_to_intlist(authentication_tag
), self
.iv
[:12]))
79 self
.assertEqual(decrypted
.rstrip(b
'\x08'), self
.secret_msg
)
81 decrypted
= aes_gcm_decrypt_and_verify_bytes(
82 data
, intlist_to_bytes(self
.key
), authentication_tag
, intlist_to_bytes(self
.iv
[:12]))
83 self
.assertEqual(decrypted
.rstrip(b
'\x08'), self
.secret_msg
)
85 def test_decrypt_text(self
):
86 password
= intlist_to_bytes(self
.key
).decode()
87 encrypted
= base64
.b64encode(
88 intlist_to_bytes(self
.iv
[:8])
89 + b
'\x17\x15\x93\xab\x8d\x80V\xcdV\xe0\t\xcdo\xc2\xa5\xd8ksM\r\xe27N\xae'
91 decrypted
= (aes_decrypt_text(encrypted
, password
, 16))
92 self
.assertEqual(decrypted
, self
.secret_msg
)
94 password
= intlist_to_bytes(self
.key
).decode()
95 encrypted
= base64
.b64encode(
96 intlist_to_bytes(self
.iv
[:8])
97 + b
'\x0b\xe6\xa4\xd9z\x0e\xb8\xb9\xd0\xd4i_\x85\x1d\x99\x98_\xe5\x80\xe7.\xbf\xa5\x83'
99 decrypted
= (aes_decrypt_text(encrypted
, password
, 32))
100 self
.assertEqual(decrypted
, self
.secret_msg
)
102 def test_ecb_encrypt(self
):
103 data
= bytes_to_intlist(self
.secret_msg
)
104 data
+= [0x08] * (BLOCK_SIZE_BYTES
- len(data
) % BLOCK_SIZE_BYTES
)
105 encrypted
= intlist_to_bytes(aes_ecb_encrypt(data
, self
.key
, self
.iv
))
108 b
'\xaa\x86]\x81\x97>\x02\x92\x9d\x1bR[[L/u\xd3&\xd1(h\xde{\x81\x94\xba\x02\xae\xbd\xa6\xd0:')
110 def test_ecb_decrypt(self
):
111 data
= bytes_to_intlist(b
'\xaa\x86]\x81\x97>\x02\x92\x9d\x1bR[[L/u\xd3&\xd1(h\xde{\x81\x94\xba\x02\xae\xbd\xa6\xd0:')
112 decrypted
= intlist_to_bytes(aes_ecb_decrypt(data
, self
.key
, self
.iv
))
113 self
.assertEqual(decrypted
.rstrip(b
'\x08'), self
.secret_msg
)
116 if __name__
== '__main__':