]>
jfr.im git - yt-dlp.git/blob - yt_dlp/aes.py
01818df61cd2042c7c4eabf0f20d50d102f619d0
3 from .compat
import compat_b64decode
, compat_ord
, compat_pycrypto_AES
4 from .utils
import bytes_to_intlist
, intlist_to_bytes
6 if compat_pycrypto_AES
:
7 def aes_cbc_decrypt_bytes(data
, key
, iv
):
8 """ Decrypt bytes with AES-CBC using pycryptodome """
9 return compat_pycrypto_AES
.new(key
, compat_pycrypto_AES
.MODE_CBC
, iv
).decrypt(data
)
11 def aes_gcm_decrypt_and_verify_bytes(data
, key
, tag
, nonce
):
12 """ Decrypt bytes with AES-GCM using pycryptodome """
13 return compat_pycrypto_AES
.new(key
, compat_pycrypto_AES
.MODE_GCM
, nonce
).decrypt_and_verify(data
, tag
)
16 def aes_cbc_decrypt_bytes(data
, key
, iv
):
17 """ Decrypt bytes with AES-CBC using native implementation since pycryptodome is unavailable """
18 return intlist_to_bytes(aes_cbc_decrypt(*map(bytes_to_intlist
, (data
, key
, iv
))))
20 def aes_gcm_decrypt_and_verify_bytes(data
, key
, tag
, nonce
):
21 """ Decrypt bytes with AES-GCM using native implementation since pycryptodome is unavailable """
22 return intlist_to_bytes(aes_gcm_decrypt_and_verify(*map(bytes_to_intlist
, (data
, key
, tag
, nonce
))))
25 def unpad_pkcs7(data
):
26 return data
[:-compat_ord(data
[-1])]
32 def aes_ecb_encrypt(data
, key
, iv
=None):
34 Encrypt with aes in ECB mode
36 @param {int[]} data cleartext
37 @param {int[]} key 16/24/32-Byte cipher key
38 @param {int[]} iv Unused for this mode
39 @returns {int[]} encrypted data
41 expanded_key
= key_expansion(key
)
42 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
45 for i
in range(block_count
):
46 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
47 encrypted_data
+= aes_encrypt(block
, expanded_key
)
48 encrypted_data
= encrypted_data
[:len(data
)]
53 def aes_ecb_decrypt(data
, key
, iv
=None):
55 Decrypt with aes in ECB mode
57 @param {int[]} data cleartext
58 @param {int[]} key 16/24/32-Byte cipher key
59 @param {int[]} iv Unused for this mode
60 @returns {int[]} decrypted data
62 expanded_key
= key_expansion(key
)
63 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
66 for i
in range(block_count
):
67 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
68 encrypted_data
+= aes_decrypt(block
, expanded_key
)
69 encrypted_data
= encrypted_data
[:len(data
)]
74 def aes_ctr_decrypt(data
, key
, iv
):
76 Decrypt with aes in counter mode
78 @param {int[]} data cipher
79 @param {int[]} key 16/24/32-Byte cipher key
80 @param {int[]} iv 16-Byte initialization vector
81 @returns {int[]} decrypted data
83 return aes_ctr_encrypt(data
, key
, iv
)
86 def aes_ctr_encrypt(data
, key
, iv
):
88 Encrypt with aes in counter mode
90 @param {int[]} data cleartext
91 @param {int[]} key 16/24/32-Byte cipher key
92 @param {int[]} iv 16-Byte initialization vector
93 @returns {int[]} encrypted data
95 expanded_key
= key_expansion(key
)
96 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
97 counter
= iter_vector(iv
)
100 for i
in range(block_count
):
101 counter_block
= next(counter
)
102 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
103 block
+= [0] * (BLOCK_SIZE_BYTES
- len(block
))
105 cipher_counter_block
= aes_encrypt(counter_block
, expanded_key
)
106 encrypted_data
+= xor(block
, cipher_counter_block
)
107 encrypted_data
= encrypted_data
[:len(data
)]
109 return encrypted_data
112 def aes_cbc_decrypt(data
, key
, iv
):
114 Decrypt with aes in CBC mode
116 @param {int[]} data cipher
117 @param {int[]} key 16/24/32-Byte cipher key
118 @param {int[]} iv 16-Byte IV
119 @returns {int[]} decrypted data
121 expanded_key
= key_expansion(key
)
122 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
125 previous_cipher_block
= iv
126 for i
in range(block_count
):
127 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
128 block
+= [0] * (BLOCK_SIZE_BYTES
- len(block
))
130 decrypted_block
= aes_decrypt(block
, expanded_key
)
131 decrypted_data
+= xor(decrypted_block
, previous_cipher_block
)
132 previous_cipher_block
= block
133 decrypted_data
= decrypted_data
[:len(data
)]
135 return decrypted_data
138 def aes_cbc_encrypt(data
, key
, iv
):
140 Encrypt with aes in CBC mode. Using PKCS#7 padding
142 @param {int[]} data cleartext
143 @param {int[]} key 16/24/32-Byte cipher key
144 @param {int[]} iv 16-Byte IV
145 @returns {int[]} encrypted data
147 expanded_key
= key_expansion(key
)
148 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
151 previous_cipher_block
= iv
152 for i
in range(block_count
):
153 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
154 remaining_length
= BLOCK_SIZE_BYTES
- len(block
)
155 block
+= [remaining_length
] * remaining_length
156 mixed_block
= xor(block
, previous_cipher_block
)
158 encrypted_block
= aes_encrypt(mixed_block
, expanded_key
)
159 encrypted_data
+= encrypted_block
161 previous_cipher_block
= encrypted_block
163 return encrypted_data
166 def aes_gcm_decrypt_and_verify(data
, key
, tag
, nonce
):
168 Decrypt with aes in GBM mode and checks authenticity using tag
170 @param {int[]} data cipher
171 @param {int[]} key 16-Byte cipher key
172 @param {int[]} tag authentication tag
173 @param {int[]} nonce IV (recommended 12-Byte)
174 @returns {int[]} decrypted data
177 # XXX: check aes, gcm param
179 hash_subkey
= aes_encrypt([0] * BLOCK_SIZE_BYTES
, key_expansion(key
))
182 j0
= nonce
+ [0, 0, 0, 1]
184 fill
= (BLOCK_SIZE_BYTES
- (len(nonce
) % BLOCK_SIZE_BYTES
)) % BLOCK_SIZE_BYTES
+ 8
185 ghash_in
= nonce
+ [0] * fill
+ bytes_to_intlist((8 * len(nonce
)).to_bytes(8, 'big'))
186 j0
= ghash(hash_subkey
, ghash_in
)
188 # TODO: add nonce support to aes_ctr_decrypt
190 # nonce_ctr = j0[:12]
193 decrypted_data
= aes_ctr_decrypt(data
, key
, iv_ctr
+ [0] * (BLOCK_SIZE_BYTES
- len(iv_ctr
)))
194 pad_len
= len(data
) // 16 * 16
198 + [0] * (BLOCK_SIZE_BYTES
- len(data
) + pad_len
) # pad
199 + bytes_to_intlist((0 * 8).to_bytes(8, 'big') # length of associated data
200 + ((len(data
) * 8).to_bytes(8, 'big'))) # length of data
203 if tag
!= aes_ctr_encrypt(s_tag
, key
, j0
):
204 raise ValueError("Mismatching authentication tag")
206 return decrypted_data
209 def aes_encrypt(data
, expanded_key
):
211 Encrypt one block with aes
213 @param {int[]} data 16-Byte state
214 @param {int[]} expanded_key 176/208/240-Byte expanded key
215 @returns {int[]} 16-Byte cipher
217 rounds
= len(expanded_key
) // BLOCK_SIZE_BYTES
- 1
219 data
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
])
220 for i
in range(1, rounds
+ 1):
221 data
= sub_bytes(data
)
222 data
= shift_rows(data
)
224 data
= list(iter_mix_columns(data
, MIX_COLUMN_MATRIX
))
225 data
= xor(data
, expanded_key
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
])
230 def aes_decrypt(data
, expanded_key
):
232 Decrypt one block with aes
234 @param {int[]} data 16-Byte cipher
235 @param {int[]} expanded_key 176/208/240-Byte expanded key
236 @returns {int[]} 16-Byte state
238 rounds
= len(expanded_key
) // BLOCK_SIZE_BYTES
- 1
240 for i
in range(rounds
, 0, -1):
241 data
= xor(data
, expanded_key
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
])
243 data
= list(iter_mix_columns(data
, MIX_COLUMN_MATRIX_INV
))
244 data
= shift_rows_inv(data
)
245 data
= sub_bytes_inv(data
)
246 data
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
])
251 def aes_decrypt_text(data
, password
, key_size_bytes
):
254 - The first 8 Bytes of decoded 'data' are the 8 high Bytes of the counter
255 - The cipher key is retrieved by encrypting the first 16 Byte of 'password'
256 with the first 'key_size_bytes' Bytes from 'password' (if necessary filled with 0's)
257 - Mode of operation is 'counter'
259 @param {str} data Base64 encoded string
260 @param {str,unicode} password Password (will be encoded with utf-8)
261 @param {int} key_size_bytes Possible values: 16 for 128-Bit, 24 for 192-Bit or 32 for 256-Bit
262 @returns {str} Decrypted data
264 NONCE_LENGTH_BYTES
= 8
266 data
= bytes_to_intlist(compat_b64decode(data
))
267 password
= bytes_to_intlist(password
.encode('utf-8'))
269 key
= password
[:key_size_bytes
] + [0] * (key_size_bytes
- len(password
))
270 key
= aes_encrypt(key
[:BLOCK_SIZE_BYTES
], key_expansion(key
)) * (key_size_bytes
// BLOCK_SIZE_BYTES
)
272 nonce
= data
[:NONCE_LENGTH_BYTES
]
273 cipher
= data
[NONCE_LENGTH_BYTES
:]
275 decrypted_data
= aes_ctr_decrypt(cipher
, key
, nonce
+ [0] * (BLOCK_SIZE_BYTES
- NONCE_LENGTH_BYTES
))
276 plaintext
= intlist_to_bytes(decrypted_data
)
281 RCON
= (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36)
282 SBOX
= (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
283 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
284 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
285 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
286 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
287 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
288 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
289 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
290 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
291 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
292 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
293 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
294 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
295 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
296 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
297 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16)
298 SBOX_INV
= (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
299 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
300 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
301 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
302 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
303 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
304 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
305 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
306 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
307 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
308 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
309 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
310 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
311 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
312 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
313 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d)
314 MIX_COLUMN_MATRIX
= ((0x2, 0x3, 0x1, 0x1),
315 (0x1, 0x2, 0x3, 0x1),
316 (0x1, 0x1, 0x2, 0x3),
317 (0x3, 0x1, 0x1, 0x2))
318 MIX_COLUMN_MATRIX_INV
= ((0xE, 0xB, 0xD, 0x9),
319 (0x9, 0xE, 0xB, 0xD),
320 (0xD, 0x9, 0xE, 0xB),
321 (0xB, 0xD, 0x9, 0xE))
322 RIJNDAEL_EXP_TABLE
= (0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,
323 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,
324 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,
325 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,
326 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,
327 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,
328 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,
329 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,
330 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,
331 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,
332 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,
333 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,
334 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,
335 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,
336 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,
337 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01)
338 RIJNDAEL_LOG_TABLE
= (0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03,
339 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1,
340 0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78,
341 0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e,
342 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38,
343 0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10,
344 0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba,
345 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57,
346 0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8,
347 0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0,
348 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7,
349 0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d,
350 0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1,
351 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab,
352 0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5,
353 0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07)
356 def key_expansion(data
):
358 Generate key schedule
360 @param {int[]} data 16/24/32-Byte cipher key
361 @returns {int[]} 176/208/240-Byte expanded key
363 data
= data
[:] # copy
365 key_size_bytes
= len(data
)
366 expanded_key_size_bytes
= (key_size_bytes
// 4 + 7) * BLOCK_SIZE_BYTES
368 while len(data
) < expanded_key_size_bytes
:
370 temp
= key_schedule_core(temp
, rcon_iteration
)
372 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
376 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
378 if key_size_bytes
== 32:
380 temp
= sub_bytes(temp
)
381 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
383 for _
in range(3 if key_size_bytes
== 32 else 2 if key_size_bytes
== 24 else 0):
385 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
386 data
= data
[:expanded_key_size_bytes
]
398 return [SBOX
[x
] for x
in data
]
401 def sub_bytes_inv(data
):
402 return [SBOX_INV
[x
] for x
in data
]
406 return data
[1:] + [data
[0]]
409 def key_schedule_core(data
, rcon_iteration
):
411 data
= sub_bytes(data
)
412 data
[0] = data
[0] ^ RCON
[rcon_iteration
]
417 def xor(data1
, data2
):
418 return [x ^ y
for x
, y
in zip(data1
, data2
)]
421 def iter_mix_columns(data
, matrix
):
422 for i
in (0, 4, 8, 12):
427 mixed ^
= (0 if data
[i
:i
+ 4][j
] == 0 or row
[j
] == 0 else
428 RIJNDAEL_EXP_TABLE
[(RIJNDAEL_LOG_TABLE
[data
[i
+ j
]] + RIJNDAEL_LOG_TABLE
[row
[j
]]) % 0xFF])
432 def shift_rows(data
):
433 return [data
[((column
+ row
) & 0b11) * 4 + row
] for column
in range(4) for row
in range(4)]
436 def shift_rows_inv(data
):
437 return [data
[((column
- row
) & 0b11) * 4 + row
] for column
in range(4) for row
in range(4)]
440 def shift_block(data
):
449 data_shifted
.append(n
)
455 data
= data
[:] # copy
456 for i
in range(len(data
) - 1, -1, -1):
460 data
[i
] = data
[i
] + 1
465 def block_product(block_x
, block_y
):
466 # NIST SP 800-38D, Algorithm 1
468 if len(block_x
) != BLOCK_SIZE_BYTES
or len(block_y
) != BLOCK_SIZE_BYTES
:
469 raise ValueError("Length of blocks need to be %d bytes" % BLOCK_SIZE_BYTES
)
471 block_r
= [0xE1] + [0] * (BLOCK_SIZE_BYTES
- 1)
473 block_z
= [0] * BLOCK_SIZE_BYTES
476 for bit
in range(7, -1, -1):
478 block_z
= xor(block_z
, block_v
)
480 do_xor
= block_v
[-1] & 1
481 block_v
= shift_block(block_v
)
483 block_v
= xor(block_v
, block_r
)
488 def ghash(subkey
, data
):
489 # NIST SP 800-38D, Algorithm 2
491 if len(data
) % BLOCK_SIZE_BYTES
:
492 raise ValueError("Length of data should be %d bytes" % BLOCK_SIZE_BYTES
)
494 last_y
= [0] * BLOCK_SIZE_BYTES
495 for i
in range(0, len(data
), BLOCK_SIZE_BYTES
):
496 block
= data
[i
: i
+ BLOCK_SIZE_BYTES
] # noqa: E203
497 last_y
= block_product(xor(last_y
, block
), subkey
)
505 'aes_cbc_decrypt_bytes',
508 'aes_gcm_decrypt_and_verify',
509 'aes_gcm_decrypt_and_verify_bytes',