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