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