]>
jfr.im git - yt-dlp.git/blob - yt_dlp/aes.py
4 from .compat
import compat_ord
5 from .dependencies
import Cryptodome_AES
6 from .utils
import bytes_to_intlist
, intlist_to_bytes
9 def aes_cbc_decrypt_bytes(data
, key
, iv
):
10 """ Decrypt bytes with AES-CBC using pycryptodome """
11 return Cryptodome_AES
.new(key
, Cryptodome_AES
.MODE_CBC
, iv
).decrypt(data
)
13 def aes_gcm_decrypt_and_verify_bytes(data
, key
, tag
, nonce
):
14 """ Decrypt bytes with AES-GCM using pycryptodome """
15 return Cryptodome_AES
.new(key
, Cryptodome_AES
.MODE_GCM
, nonce
).decrypt_and_verify(data
, tag
)
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
))))
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
))))
27 def unpad_pkcs7(data
):
28 return data
[:-compat_ord(data
[-1])]
34 def pad_block(block
, padding_mode
):
36 Pad a block with the given padding mode
37 @param {int[]} block block to pad
38 @param padding_mode padding mode
40 padding_size
= BLOCK_SIZE_BYTES
- len(block
)
43 'pkcs7': padding_size
,
50 raise ValueError('Block size exceeded')
51 elif padding_mode
not in PADDING_BYTE
:
52 raise NotImplementedError(f
'Padding mode {padding_mode} is not implemented')
54 if padding_mode
== 'iso7816' and padding_size
:
55 block
= block
+ [0x80] # NB: += mutates list
58 return block
+ [PADDING_BYTE
[padding_mode
]] * padding_size
61 def aes_ecb_encrypt(data
, key
, iv
=None):
63 Encrypt with aes in ECB mode
65 @param {int[]} data cleartext
66 @param {int[]} key 16/24/32-Byte cipher key
67 @param {int[]} iv Unused for this mode
68 @returns {int[]} encrypted data
70 expanded_key
= key_expansion(key
)
71 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
74 for i
in range(block_count
):
75 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
76 encrypted_data
+= aes_encrypt(block
, expanded_key
)
77 encrypted_data
= encrypted_data
[:len(data
)]
82 def aes_ecb_decrypt(data
, key
, iv
=None):
84 Decrypt with aes in ECB mode
86 @param {int[]} data cleartext
87 @param {int[]} key 16/24/32-Byte cipher key
88 @param {int[]} iv Unused for this mode
89 @returns {int[]} decrypted data
91 expanded_key
= key_expansion(key
)
92 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
95 for i
in range(block_count
):
96 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
97 encrypted_data
+= aes_decrypt(block
, expanded_key
)
98 encrypted_data
= encrypted_data
[:len(data
)]
100 return encrypted_data
103 def aes_ctr_decrypt(data
, key
, iv
):
105 Decrypt with aes in counter mode
107 @param {int[]} data cipher
108 @param {int[]} key 16/24/32-Byte cipher key
109 @param {int[]} iv 16-Byte initialization vector
110 @returns {int[]} decrypted data
112 return aes_ctr_encrypt(data
, key
, iv
)
115 def aes_ctr_encrypt(data
, key
, iv
):
117 Encrypt with aes in counter mode
119 @param {int[]} data cleartext
120 @param {int[]} key 16/24/32-Byte cipher key
121 @param {int[]} iv 16-Byte initialization vector
122 @returns {int[]} encrypted data
124 expanded_key
= key_expansion(key
)
125 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
126 counter
= iter_vector(iv
)
129 for i
in range(block_count
):
130 counter_block
= next(counter
)
131 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
132 block
+= [0] * (BLOCK_SIZE_BYTES
- len(block
))
134 cipher_counter_block
= aes_encrypt(counter_block
, expanded_key
)
135 encrypted_data
+= xor(block
, cipher_counter_block
)
136 encrypted_data
= encrypted_data
[:len(data
)]
138 return encrypted_data
141 def aes_cbc_decrypt(data
, key
, iv
):
143 Decrypt with aes in CBC mode
145 @param {int[]} data cipher
146 @param {int[]} key 16/24/32-Byte cipher key
147 @param {int[]} iv 16-Byte IV
148 @returns {int[]} decrypted data
150 expanded_key
= key_expansion(key
)
151 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
154 previous_cipher_block
= iv
155 for i
in range(block_count
):
156 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
157 block
+= [0] * (BLOCK_SIZE_BYTES
- len(block
))
159 decrypted_block
= aes_decrypt(block
, expanded_key
)
160 decrypted_data
+= xor(decrypted_block
, previous_cipher_block
)
161 previous_cipher_block
= block
162 decrypted_data
= decrypted_data
[:len(data
)]
164 return decrypted_data
167 def aes_cbc_encrypt(data
, key
, iv
, padding_mode
='pkcs7'):
169 Encrypt with aes in CBC mode
171 @param {int[]} data cleartext
172 @param {int[]} key 16/24/32-Byte cipher key
173 @param {int[]} iv 16-Byte IV
174 @param padding_mode Padding mode to use
175 @returns {int[]} encrypted data
177 expanded_key
= key_expansion(key
)
178 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
181 previous_cipher_block
= iv
182 for i
in range(block_count
):
183 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
184 block
= pad_block(block
, padding_mode
)
186 mixed_block
= xor(block
, previous_cipher_block
)
188 encrypted_block
= aes_encrypt(mixed_block
, expanded_key
)
189 encrypted_data
+= encrypted_block
191 previous_cipher_block
= encrypted_block
193 return encrypted_data
196 def aes_gcm_decrypt_and_verify(data
, key
, tag
, nonce
):
198 Decrypt with aes in GBM mode and checks authenticity using tag
200 @param {int[]} data cipher
201 @param {int[]} key 16-Byte cipher key
202 @param {int[]} tag authentication tag
203 @param {int[]} nonce IV (recommended 12-Byte)
204 @returns {int[]} decrypted data
207 # XXX: check aes, gcm param
209 hash_subkey
= aes_encrypt([0] * BLOCK_SIZE_BYTES
, key_expansion(key
))
212 j0
= nonce
+ [0, 0, 0, 1]
214 fill
= (BLOCK_SIZE_BYTES
- (len(nonce
) % BLOCK_SIZE_BYTES
)) % BLOCK_SIZE_BYTES
+ 8
215 ghash_in
= nonce
+ [0] * fill
+ bytes_to_intlist((8 * len(nonce
)).to_bytes(8, 'big'))
216 j0
= ghash(hash_subkey
, ghash_in
)
218 # TODO: add nonce support to aes_ctr_decrypt
220 # nonce_ctr = j0[:12]
223 decrypted_data
= aes_ctr_decrypt(data
, key
, iv_ctr
+ [0] * (BLOCK_SIZE_BYTES
- len(iv_ctr
)))
224 pad_len
= len(data
) // 16 * 16
228 + [0] * (BLOCK_SIZE_BYTES
- len(data
) + pad_len
) # pad
229 + bytes_to_intlist((0 * 8).to_bytes(8, 'big') # length of associated data
230 + ((len(data
) * 8).to_bytes(8, 'big'))) # length of data
233 if tag
!= aes_ctr_encrypt(s_tag
, key
, j0
):
234 raise ValueError("Mismatching authentication tag")
236 return decrypted_data
239 def aes_encrypt(data
, expanded_key
):
241 Encrypt one block with aes
243 @param {int[]} data 16-Byte state
244 @param {int[]} expanded_key 176/208/240-Byte expanded key
245 @returns {int[]} 16-Byte cipher
247 rounds
= len(expanded_key
) // BLOCK_SIZE_BYTES
- 1
249 data
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
])
250 for i
in range(1, rounds
+ 1):
251 data
= sub_bytes(data
)
252 data
= shift_rows(data
)
254 data
= list(iter_mix_columns(data
, MIX_COLUMN_MATRIX
))
255 data
= xor(data
, expanded_key
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
])
260 def aes_decrypt(data
, expanded_key
):
262 Decrypt one block with aes
264 @param {int[]} data 16-Byte cipher
265 @param {int[]} expanded_key 176/208/240-Byte expanded key
266 @returns {int[]} 16-Byte state
268 rounds
= len(expanded_key
) // BLOCK_SIZE_BYTES
- 1
270 for i
in range(rounds
, 0, -1):
271 data
= xor(data
, expanded_key
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
])
273 data
= list(iter_mix_columns(data
, MIX_COLUMN_MATRIX_INV
))
274 data
= shift_rows_inv(data
)
275 data
= sub_bytes_inv(data
)
276 data
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
])
281 def aes_decrypt_text(data
, password
, key_size_bytes
):
284 - The first 8 Bytes of decoded 'data' are the 8 high Bytes of the counter
285 - The cipher key is retrieved by encrypting the first 16 Byte of 'password'
286 with the first 'key_size_bytes' Bytes from 'password' (if necessary filled with 0's)
287 - Mode of operation is 'counter'
289 @param {str} data Base64 encoded string
290 @param {str,unicode} password Password (will be encoded with utf-8)
291 @param {int} key_size_bytes Possible values: 16 for 128-Bit, 24 for 192-Bit or 32 for 256-Bit
292 @returns {str} Decrypted data
294 NONCE_LENGTH_BYTES
= 8
296 data
= bytes_to_intlist(base64
.b64decode(data
))
297 password
= bytes_to_intlist(password
.encode())
299 key
= password
[:key_size_bytes
] + [0] * (key_size_bytes
- len(password
))
300 key
= aes_encrypt(key
[:BLOCK_SIZE_BYTES
], key_expansion(key
)) * (key_size_bytes
// BLOCK_SIZE_BYTES
)
302 nonce
= data
[:NONCE_LENGTH_BYTES
]
303 cipher
= data
[NONCE_LENGTH_BYTES
:]
305 decrypted_data
= aes_ctr_decrypt(cipher
, key
, nonce
+ [0] * (BLOCK_SIZE_BYTES
- NONCE_LENGTH_BYTES
))
306 plaintext
= intlist_to_bytes(decrypted_data
)
311 RCON
= (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36)
312 SBOX
= (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
313 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
314 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
315 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
316 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
317 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
318 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
319 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
320 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
321 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
322 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
323 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
324 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
325 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
326 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
327 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16)
328 SBOX_INV
= (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
329 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
330 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
331 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
332 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
333 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
334 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
335 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
336 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
337 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
338 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
339 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
340 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
341 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
342 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
343 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d)
344 MIX_COLUMN_MATRIX
= ((0x2, 0x3, 0x1, 0x1),
345 (0x1, 0x2, 0x3, 0x1),
346 (0x1, 0x1, 0x2, 0x3),
347 (0x3, 0x1, 0x1, 0x2))
348 MIX_COLUMN_MATRIX_INV
= ((0xE, 0xB, 0xD, 0x9),
349 (0x9, 0xE, 0xB, 0xD),
350 (0xD, 0x9, 0xE, 0xB),
351 (0xB, 0xD, 0x9, 0xE))
352 RIJNDAEL_EXP_TABLE
= (0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,
353 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,
354 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,
355 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,
356 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,
357 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,
358 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,
359 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,
360 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,
361 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,
362 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,
363 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,
364 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,
365 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,
366 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,
367 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01)
368 RIJNDAEL_LOG_TABLE
= (0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03,
369 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1,
370 0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78,
371 0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e,
372 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38,
373 0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10,
374 0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba,
375 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57,
376 0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8,
377 0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0,
378 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7,
379 0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d,
380 0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1,
381 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab,
382 0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5,
383 0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07)
386 def key_expansion(data
):
388 Generate key schedule
390 @param {int[]} data 16/24/32-Byte cipher key
391 @returns {int[]} 176/208/240-Byte expanded key
393 data
= data
[:] # copy
395 key_size_bytes
= len(data
)
396 expanded_key_size_bytes
= (key_size_bytes
// 4 + 7) * BLOCK_SIZE_BYTES
398 while len(data
) < expanded_key_size_bytes
:
400 temp
= key_schedule_core(temp
, rcon_iteration
)
402 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
406 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
408 if key_size_bytes
== 32:
410 temp
= sub_bytes(temp
)
411 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
413 for _
in range(3 if key_size_bytes
== 32 else 2 if key_size_bytes
== 24 else 0):
415 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
416 data
= data
[:expanded_key_size_bytes
]
428 return [SBOX
[x
] for x
in data
]
431 def sub_bytes_inv(data
):
432 return [SBOX_INV
[x
] for x
in data
]
436 return data
[1:] + [data
[0]]
439 def key_schedule_core(data
, rcon_iteration
):
441 data
= sub_bytes(data
)
442 data
[0] = data
[0] ^ RCON
[rcon_iteration
]
447 def xor(data1
, data2
):
448 return [x ^ y
for x
, y
in zip(data1
, data2
)]
451 def iter_mix_columns(data
, matrix
):
452 for i
in (0, 4, 8, 12):
457 mixed ^
= (0 if data
[i
:i
+ 4][j
] == 0 or row
[j
] == 0 else
458 RIJNDAEL_EXP_TABLE
[(RIJNDAEL_LOG_TABLE
[data
[i
+ j
]] + RIJNDAEL_LOG_TABLE
[row
[j
]]) % 0xFF])
462 def shift_rows(data
):
463 return [data
[((column
+ row
) & 0b11) * 4 + row
] for column
in range(4) for row
in range(4)]
466 def shift_rows_inv(data
):
467 return [data
[((column
- row
) & 0b11) * 4 + row
] for column
in range(4) for row
in range(4)]
470 def shift_block(data
):
479 data_shifted
.append(n
)
485 data
= data
[:] # copy
486 for i
in range(len(data
) - 1, -1, -1):
490 data
[i
] = data
[i
] + 1
495 def block_product(block_x
, block_y
):
496 # NIST SP 800-38D, Algorithm 1
498 if len(block_x
) != BLOCK_SIZE_BYTES
or len(block_y
) != BLOCK_SIZE_BYTES
:
499 raise ValueError("Length of blocks need to be %d bytes" % BLOCK_SIZE_BYTES
)
501 block_r
= [0xE1] + [0] * (BLOCK_SIZE_BYTES
- 1)
503 block_z
= [0] * BLOCK_SIZE_BYTES
506 for bit
in range(7, -1, -1):
508 block_z
= xor(block_z
, block_v
)
510 do_xor
= block_v
[-1] & 1
511 block_v
= shift_block(block_v
)
513 block_v
= xor(block_v
, block_r
)
518 def ghash(subkey
, data
):
519 # NIST SP 800-38D, Algorithm 2
521 if len(data
) % BLOCK_SIZE_BYTES
:
522 raise ValueError("Length of data should be %d bytes" % BLOCK_SIZE_BYTES
)
524 last_y
= [0] * BLOCK_SIZE_BYTES
525 for i
in range(0, len(data
), BLOCK_SIZE_BYTES
):
526 block
= data
[i
: i
+ BLOCK_SIZE_BYTES
]
527 last_y
= block_product(xor(last_y
, block
), subkey
)
535 'aes_cbc_decrypt_bytes',
538 'aes_gcm_decrypt_and_verify',
539 'aes_gcm_decrypt_and_verify_bytes',