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