]> jfr.im git - yt-dlp.git/blame - yt_dlp/aes.py
Better warning when requested subs format not found (#9873)
[yt-dlp.git] / yt_dlp / aes.py
CommitLineData
14f25df2 1import base64
f3bcebb1 2from math import ceil
3
14f25df2 4from .compat import compat_ord
f6a765ce 5from .dependencies import Cryptodome
f8271158 6from .utils import bytes_to_intlist, intlist_to_bytes
edf65256 7
65f6e807 8if Cryptodome.AES:
edf65256 9 def aes_cbc_decrypt_bytes(data, key, iv):
10 """ Decrypt bytes with AES-CBC using pycryptodome """
65f6e807 11 return Cryptodome.AES.new(key, Cryptodome.AES.MODE_CBC, iv).decrypt(data)
edf65256 12
09906f55
ÁS
13 def aes_gcm_decrypt_and_verify_bytes(data, key, tag, nonce):
14 """ Decrypt bytes with AES-GCM using pycryptodome """
65f6e807 15 return Cryptodome.AES.new(key, Cryptodome.AES.MODE_GCM, nonce).decrypt_and_verify(data, tag)
09906f55 16
edf65256 17else:
18 def aes_cbc_decrypt_bytes(data, key, iv):
19 """ Decrypt bytes with AES-CBC using native implementation since pycryptodome is unavailable """
20 return intlist_to_bytes(aes_cbc_decrypt(*map(bytes_to_intlist, (data, key, iv))))
21
09906f55
ÁS
22 def aes_gcm_decrypt_and_verify_bytes(data, key, tag, nonce):
23 """ Decrypt bytes with AES-GCM using native implementation since pycryptodome is unavailable """
24 return intlist_to_bytes(aes_gcm_decrypt_and_verify(*map(bytes_to_intlist, (data, key, tag, nonce))))
25
edf65256 26
c6e07cf1 27def aes_cbc_encrypt_bytes(data, key, iv, **kwargs):
28 return intlist_to_bytes(aes_cbc_encrypt(*map(bytes_to_intlist, (data, key, iv)), **kwargs))
29
30
db4678e4 31BLOCK_SIZE_BYTES = 16
32
33
1d3586d0 34def unpad_pkcs7(data):
35 return data[:-compat_ord(data[-1])]
36
37
db4678e4 38def pkcs7_padding(data):
39 """
40 PKCS#7 padding
41
42 @param {int[]} data cleartext
43 @returns {int[]} padding data
44 """
45
46 remaining_length = BLOCK_SIZE_BYTES - len(data) % BLOCK_SIZE_BYTES
47 return data + [remaining_length] * remaining_length
f3bcebb1 48
5f6a1245 49
7a7eeb10
E
50def pad_block(block, padding_mode):
51 """
52 Pad a block with the given padding mode
53 @param {int[]} block block to pad
54 @param padding_mode padding mode
55 """
56 padding_size = BLOCK_SIZE_BYTES - len(block)
57
58 PADDING_BYTE = {
59 'pkcs7': padding_size,
60 'iso7816': 0x0,
61 'whitespace': 0x20,
62 'zero': 0x0,
63 }
64
65 if padding_size < 0:
66 raise ValueError('Block size exceeded')
67 elif padding_mode not in PADDING_BYTE:
68 raise NotImplementedError(f'Padding mode {padding_mode} is not implemented')
69
70 if padding_mode == 'iso7816' and padding_size:
71 block = block + [0x80] # NB: += mutates list
72 padding_size -= 1
73
74 return block + [PADDING_BYTE[padding_mode]] * padding_size
75
76
a04e0055
THD
77def aes_ecb_encrypt(data, key, iv=None):
78 """
db4678e4 79 Encrypt with aes in ECB mode. Using PKCS#7 padding
a04e0055
THD
80
81 @param {int[]} data cleartext
82 @param {int[]} key 16/24/32-Byte cipher key
83 @param {int[]} iv Unused for this mode
84 @returns {int[]} encrypted data
85 """
86 expanded_key = key_expansion(key)
87 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
88
89 encrypted_data = []
90 for i in range(block_count):
91 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
db4678e4 92 encrypted_data += aes_encrypt(pkcs7_padding(block), expanded_key)
a04e0055
THD
93
94 return encrypted_data
95
96
97def aes_ecb_decrypt(data, key, iv=None):
98 """
99 Decrypt with aes in ECB mode
100
101 @param {int[]} data cleartext
102 @param {int[]} key 16/24/32-Byte cipher key
103 @param {int[]} iv Unused for this mode
104 @returns {int[]} decrypted data
105 """
106 expanded_key = key_expansion(key)
107 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
108
109 encrypted_data = []
110 for i in range(block_count):
111 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
112 encrypted_data += aes_decrypt(block, expanded_key)
113 encrypted_data = encrypted_data[:len(data)]
114
115 return encrypted_data
116
117
09906f55 118def aes_ctr_decrypt(data, key, iv):
f3bcebb1 119 """
120 Decrypt with aes in counter mode
5f6a1245 121
f3bcebb1 122 @param {int[]} data cipher
123 @param {int[]} key 16/24/32-Byte cipher key
09906f55 124 @param {int[]} iv 16-Byte initialization vector
f3bcebb1 125 @returns {int[]} decrypted data
126 """
09906f55
ÁS
127 return aes_ctr_encrypt(data, key, iv)
128
129
130def aes_ctr_encrypt(data, key, iv):
131 """
132 Encrypt with aes in counter mode
133
134 @param {int[]} data cleartext
135 @param {int[]} key 16/24/32-Byte cipher key
136 @param {int[]} iv 16-Byte initialization vector
137 @returns {int[]} encrypted data
138 """
f3bcebb1 139 expanded_key = key_expansion(key)
6e74bc41 140 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
09906f55 141 counter = iter_vector(iv)
5f6a1245 142
09906f55 143 encrypted_data = []
f3bcebb1 144 for i in range(block_count):
09906f55 145 counter_block = next(counter)
2514d263
JW
146 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
147 block += [0] * (BLOCK_SIZE_BYTES - len(block))
5f6a1245 148
f3bcebb1 149 cipher_counter_block = aes_encrypt(counter_block, expanded_key)
09906f55
ÁS
150 encrypted_data += xor(block, cipher_counter_block)
151 encrypted_data = encrypted_data[:len(data)]
5f6a1245 152
09906f55 153 return encrypted_data
f3bcebb1 154
5f6a1245 155
c8434e83 156def aes_cbc_decrypt(data, key, iv):
157 """
158 Decrypt with aes in CBC mode
5f6a1245 159
c8434e83 160 @param {int[]} data cipher
161 @param {int[]} key 16/24/32-Byte cipher key
162 @param {int[]} iv 16-Byte IV
163 @returns {int[]} decrypted data
164 """
165 expanded_key = key_expansion(key)
166 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
5f6a1245
JW
167
168 decrypted_data = []
c8434e83 169 previous_cipher_block = iv
170 for i in range(block_count):
2514d263
JW
171 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
172 block += [0] * (BLOCK_SIZE_BYTES - len(block))
5f6a1245 173
c8434e83 174 decrypted_block = aes_decrypt(block, expanded_key)
175 decrypted_data += xor(decrypted_block, previous_cipher_block)
176 previous_cipher_block = block
177 decrypted_data = decrypted_data[:len(data)]
5f6a1245 178
c8434e83 179 return decrypted_data
180
5f6a1245 181
c6e07cf1 182def aes_cbc_encrypt(data, key, iv, *, padding_mode='pkcs7'):
c9619f0a 183 """
7a7eeb10 184 Encrypt with aes in CBC mode
c9619f0a
YCH
185
186 @param {int[]} data cleartext
187 @param {int[]} key 16/24/32-Byte cipher key
188 @param {int[]} iv 16-Byte IV
7a7eeb10 189 @param padding_mode Padding mode to use
c9619f0a
YCH
190 @returns {int[]} encrypted data
191 """
192 expanded_key = key_expansion(key)
193 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
194
195 encrypted_data = []
196 previous_cipher_block = iv
197 for i in range(block_count):
198 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
7a7eeb10
E
199 block = pad_block(block, padding_mode)
200
c9619f0a
YCH
201 mixed_block = xor(block, previous_cipher_block)
202
203 encrypted_block = aes_encrypt(mixed_block, expanded_key)
204 encrypted_data += encrypted_block
205
206 previous_cipher_block = encrypted_block
207
208 return encrypted_data
209
210
09906f55 211def aes_gcm_decrypt_and_verify(data, key, tag, nonce):
f3bcebb1 212 """
09906f55 213 Decrypt with aes in GBM mode and checks authenticity using tag
5f6a1245 214
09906f55
ÁS
215 @param {int[]} data cipher
216 @param {int[]} key 16-Byte cipher key
217 @param {int[]} tag authentication tag
218 @param {int[]} nonce IV (recommended 12-Byte)
219 @returns {int[]} decrypted data
f3bcebb1 220 """
5f6a1245 221
09906f55 222 # XXX: check aes, gcm param
5f6a1245 223
09906f55 224 hash_subkey = aes_encrypt([0] * BLOCK_SIZE_BYTES, key_expansion(key))
5f6a1245 225
09906f55
ÁS
226 if len(nonce) == 12:
227 j0 = nonce + [0, 0, 0, 1]
228 else:
229 fill = (BLOCK_SIZE_BYTES - (len(nonce) % BLOCK_SIZE_BYTES)) % BLOCK_SIZE_BYTES + 8
230 ghash_in = nonce + [0] * fill + bytes_to_intlist((8 * len(nonce)).to_bytes(8, 'big'))
231 j0 = ghash(hash_subkey, ghash_in)
5f6a1245 232
09906f55 233 # TODO: add nonce support to aes_ctr_decrypt
5f6a1245 234
09906f55
ÁS
235 # nonce_ctr = j0[:12]
236 iv_ctr = inc(j0)
237
238 decrypted_data = aes_ctr_decrypt(data, key, iv_ctr + [0] * (BLOCK_SIZE_BYTES - len(iv_ctr)))
239 pad_len = len(data) // 16 * 16
240 s_tag = ghash(
241 hash_subkey,
242 data
243 + [0] * (BLOCK_SIZE_BYTES - len(data) + pad_len) # pad
244 + bytes_to_intlist((0 * 8).to_bytes(8, 'big') # length of associated data
245 + ((len(data) * 8).to_bytes(8, 'big'))) # length of data
246 )
247
248 if tag != aes_ctr_encrypt(s_tag, key, j0):
249 raise ValueError("Mismatching authentication tag")
250
251 return decrypted_data
f3bcebb1 252
5f6a1245 253
f3bcebb1 254def aes_encrypt(data, expanded_key):
255 """
256 Encrypt one block with aes
5f6a1245 257
f3bcebb1 258 @param {int[]} data 16-Byte state
5f6a1245 259 @param {int[]} expanded_key 176/208/240-Byte expanded key
f3bcebb1 260 @returns {int[]} 16-Byte cipher
261 """
48ea9cea 262 rounds = len(expanded_key) // BLOCK_SIZE_BYTES - 1
c8434e83 263
f3bcebb1 264 data = xor(data, expanded_key[:BLOCK_SIZE_BYTES])
2514d263 265 for i in range(1, rounds + 1):
f3bcebb1 266 data = sub_bytes(data)
267 data = shift_rows(data)
268 if i != rounds:
ff1dec81 269 data = list(iter_mix_columns(data, MIX_COLUMN_MATRIX))
2514d263 270 data = xor(data, expanded_key[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES])
c8434e83 271
272 return data
273
5f6a1245 274
c8434e83 275def aes_decrypt(data, expanded_key):
276 """
277 Decrypt one block with aes
5f6a1245 278
c8434e83 279 @param {int[]} data 16-Byte cipher
280 @param {int[]} expanded_key 176/208/240-Byte expanded key
281 @returns {int[]} 16-Byte state
282 """
283 rounds = len(expanded_key) // BLOCK_SIZE_BYTES - 1
5f6a1245 284
c8434e83 285 for i in range(rounds, 0, -1):
2514d263 286 data = xor(data, expanded_key[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES])
c8434e83 287 if i != rounds:
ff1dec81 288 data = list(iter_mix_columns(data, MIX_COLUMN_MATRIX_INV))
c8434e83 289 data = shift_rows_inv(data)
290 data = sub_bytes_inv(data)
291 data = xor(data, expanded_key[:BLOCK_SIZE_BYTES])
5f6a1245 292
f3bcebb1 293 return data
294
5f6a1245 295
f3bcebb1 296def aes_decrypt_text(data, password, key_size_bytes):
297 """
298 Decrypt text
299 - The first 8 Bytes of decoded 'data' are the 8 high Bytes of the counter
300 - The cipher key is retrieved by encrypting the first 16 Byte of 'password'
301 with the first 'key_size_bytes' Bytes from 'password' (if necessary filled with 0's)
302 - Mode of operation is 'counter'
5f6a1245 303
f3bcebb1 304 @param {str} data Base64 encoded string
305 @param {str,unicode} password Password (will be encoded with utf-8)
306 @param {int} key_size_bytes Possible values: 16 for 128-Bit, 24 for 192-Bit or 32 for 256-Bit
307 @returns {str} Decrypted data
308 """
309 NONCE_LENGTH_BYTES = 8
5f6a1245 310
14f25df2 311 data = bytes_to_intlist(base64.b64decode(data))
0f06bcd7 312 password = bytes_to_intlist(password.encode())
5f6a1245 313
2514d263 314 key = password[:key_size_bytes] + [0] * (key_size_bytes - len(password))
48ea9cea 315 key = aes_encrypt(key[:BLOCK_SIZE_BYTES], key_expansion(key)) * (key_size_bytes // BLOCK_SIZE_BYTES)
5f6a1245 316
f3bcebb1 317 nonce = data[:NONCE_LENGTH_BYTES]
318 cipher = data[NONCE_LENGTH_BYTES:]
5f6a1245 319
09906f55 320 decrypted_data = aes_ctr_decrypt(cipher, key, nonce + [0] * (BLOCK_SIZE_BYTES - NONCE_LENGTH_BYTES))
0012690a 321 plaintext = intlist_to_bytes(decrypted_data)
5f6a1245 322
f3bcebb1 323 return plaintext
324
582be358 325
f3bcebb1 326RCON = (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36)
327SBOX = (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
328 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
329 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
330 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
331 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
332 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
333 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
334 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
335 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
336 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
337 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
338 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
339 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
340 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
341 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
342 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16)
c8434e83 343SBOX_INV = (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
344 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
345 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
346 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
347 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
348 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
349 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
350 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
351 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
352 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
353 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
354 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
355 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
356 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
357 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
358 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d)
5f6a1245
JW
359MIX_COLUMN_MATRIX = ((0x2, 0x3, 0x1, 0x1),
360 (0x1, 0x2, 0x3, 0x1),
361 (0x1, 0x1, 0x2, 0x3),
362 (0x3, 0x1, 0x1, 0x2))
363MIX_COLUMN_MATRIX_INV = ((0xE, 0xB, 0xD, 0x9),
364 (0x9, 0xE, 0xB, 0xD),
365 (0xD, 0x9, 0xE, 0xB),
366 (0xB, 0xD, 0x9, 0xE))
c8434e83 367RIJNDAEL_EXP_TABLE = (0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,
368 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,
369 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,
370 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,
371 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,
372 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,
373 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,
374 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,
375 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,
376 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,
377 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,
378 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,
379 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,
380 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,
381 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,
382 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01)
383RIJNDAEL_LOG_TABLE = (0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03,
384 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1,
385 0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78,
386 0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e,
387 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38,
388 0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10,
389 0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba,
390 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57,
391 0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8,
392 0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0,
393 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7,
394 0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d,
395 0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1,
396 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab,
397 0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5,
398 0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07)
f3bcebb1 399
5f6a1245 400
09906f55
ÁS
401def key_expansion(data):
402 """
403 Generate key schedule
404
405 @param {int[]} data 16/24/32-Byte cipher key
406 @returns {int[]} 176/208/240-Byte expanded key
407 """
408 data = data[:] # copy
409 rcon_iteration = 1
410 key_size_bytes = len(data)
411 expanded_key_size_bytes = (key_size_bytes // 4 + 7) * BLOCK_SIZE_BYTES
412
413 while len(data) < expanded_key_size_bytes:
414 temp = data[-4:]
415 temp = key_schedule_core(temp, rcon_iteration)
416 rcon_iteration += 1
417 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
418
419 for _ in range(3):
420 temp = data[-4:]
421 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
422
423 if key_size_bytes == 32:
424 temp = data[-4:]
425 temp = sub_bytes(temp)
426 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
427
428 for _ in range(3 if key_size_bytes == 32 else 2 if key_size_bytes == 24 else 0):
429 temp = data[-4:]
430 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
431 data = data[:expanded_key_size_bytes]
432
433 return data
434
435
436def iter_vector(iv):
437 while True:
438 yield iv
439 iv = inc(iv)
440
441
f3bcebb1 442def sub_bytes(data):
48ea9cea 443 return [SBOX[x] for x in data]
f3bcebb1 444
5f6a1245 445
c8434e83 446def sub_bytes_inv(data):
447 return [SBOX_INV[x] for x in data]
448
5f6a1245 449
f3bcebb1 450def rotate(data):
451 return data[1:] + [data[0]]
452
5f6a1245 453
f3bcebb1 454def key_schedule_core(data, rcon_iteration):
455 data = rotate(data)
456 data = sub_bytes(data)
457 data[0] = data[0] ^ RCON[rcon_iteration]
5f6a1245 458
f3bcebb1 459 return data
460
5f6a1245 461
f3bcebb1 462def xor(data1, data2):
2514d263 463 return [x ^ y for x, y in zip(data1, data2)]
f3bcebb1 464
5f6a1245 465
ff1dec81
ÁS
466def iter_mix_columns(data, matrix):
467 for i in (0, 4, 8, 12):
468 for row in matrix:
469 mixed = 0
470 for j in range(4):
471 # xor is (+) and (-)
472 mixed ^= (0 if data[i:i + 4][j] == 0 or row[j] == 0 else
473 RIJNDAEL_EXP_TABLE[(RIJNDAEL_LOG_TABLE[data[i + j]] + RIJNDAEL_LOG_TABLE[row[j]]) % 0xFF])
474 yield mixed
c8434e83 475
5f6a1245 476
f3bcebb1 477def shift_rows(data):
ff1dec81 478 return [data[((column + row) & 0b11) * 4 + row] for column in range(4) for row in range(4)]
f3bcebb1 479
5f6a1245 480
c8434e83 481def shift_rows_inv(data):
ff1dec81 482 return [data[((column - row) & 0b11) * 4 + row] for column in range(4) for row in range(4)]
c8434e83 483
5f6a1245 484
09906f55
ÁS
485def shift_block(data):
486 data_shifted = []
487
488 bit = 0
489 for n in data:
490 if bit:
491 n |= 0x100
492 bit = n & 1
493 n >>= 1
494 data_shifted.append(n)
495
496 return data_shifted
497
498
f3bcebb1 499def inc(data):
5f6a1245 500 data = data[:] # copy
2514d263 501 for i in range(len(data) - 1, -1, -1):
f3bcebb1 502 if data[i] == 255:
503 data[i] = 0
504 else:
505 data[i] = data[i] + 1
506 break
507 return data
f36f92f4 508
582be358 509
09906f55
ÁS
510def block_product(block_x, block_y):
511 # NIST SP 800-38D, Algorithm 1
512
513 if len(block_x) != BLOCK_SIZE_BYTES or len(block_y) != BLOCK_SIZE_BYTES:
514 raise ValueError("Length of blocks need to be %d bytes" % BLOCK_SIZE_BYTES)
515
516 block_r = [0xE1] + [0] * (BLOCK_SIZE_BYTES - 1)
517 block_v = block_y[:]
518 block_z = [0] * BLOCK_SIZE_BYTES
519
520 for i in block_x:
521 for bit in range(7, -1, -1):
522 if i & (1 << bit):
523 block_z = xor(block_z, block_v)
524
525 do_xor = block_v[-1] & 1
526 block_v = shift_block(block_v)
527 if do_xor:
528 block_v = xor(block_v, block_r)
529
530 return block_z
531
532
533def ghash(subkey, data):
534 # NIST SP 800-38D, Algorithm 2
535
536 if len(data) % BLOCK_SIZE_BYTES:
537 raise ValueError("Length of data should be %d bytes" % BLOCK_SIZE_BYTES)
538
539 last_y = [0] * BLOCK_SIZE_BYTES
540 for i in range(0, len(data), BLOCK_SIZE_BYTES):
19a03940 541 block = data[i: i + BLOCK_SIZE_BYTES]
09906f55
ÁS
542 last_y = block_product(xor(last_y, block), subkey)
543
544 return last_y
545
546
547__all__ = [
09906f55
ÁS
548 'aes_cbc_decrypt',
549 'aes_cbc_decrypt_bytes',
c6e07cf1 550 'aes_ctr_decrypt',
09906f55 551 'aes_decrypt_text',
c6e07cf1 552 'aes_decrypt',
553 'aes_ecb_decrypt',
09906f55
ÁS
554 'aes_gcm_decrypt_and_verify',
555 'aes_gcm_decrypt_and_verify_bytes',
c6e07cf1 556
557 'aes_cbc_encrypt',
558 'aes_cbc_encrypt_bytes',
559 'aes_ctr_encrypt',
560 'aes_ecb_encrypt',
561 'aes_encrypt',
562
1d3586d0 563 'key_expansion',
7a7eeb10 564 'pad_block',
db4678e4 565 'pkcs7_padding',
1d3586d0 566 'unpad_pkcs7',
09906f55 567]