]>
jfr.im git - yt-dlp.git/blob - yt_dlp/aes.py
1 from __future__
import unicode_literals
5 from .compat
import compat_b64decode
, compat_pycrypto_AES
6 from .utils
import bytes_to_intlist
, intlist_to_bytes
9 if 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
)
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
)
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
))))
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
))))
31 def aes_ecb_encrypt(data
, key
, iv
=None):
33 Encrypt with aes in ECB mode
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
40 expanded_key
= key_expansion(key
)
41 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
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
)]
52 def aes_ecb_decrypt(data
, key
, iv
=None):
54 Decrypt with aes in ECB mode
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
61 expanded_key
= key_expansion(key
)
62 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
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
)]
73 def aes_ctr_decrypt(data
, key
, iv
):
75 Decrypt with aes in counter mode
77 @param {int[]} data cipher
78 @param {int[]} key 16/24/32-Byte cipher key
79 @param {int[]} iv 16-Byte initialization vector
80 @returns {int[]} decrypted data
82 return aes_ctr_encrypt(data
, key
, iv
)
85 def aes_ctr_encrypt(data
, key
, iv
):
87 Encrypt with aes in counter mode
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
94 expanded_key
= key_expansion(key
)
95 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
96 counter
= iter_vector(iv
)
99 for i
in range(block_count
):
100 counter_block
= next(counter
)
101 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
102 block
+= [0] * (BLOCK_SIZE_BYTES
- len(block
))
104 cipher_counter_block
= aes_encrypt(counter_block
, expanded_key
)
105 encrypted_data
+= xor(block
, cipher_counter_block
)
106 encrypted_data
= encrypted_data
[:len(data
)]
108 return encrypted_data
111 def aes_cbc_decrypt(data
, key
, iv
):
113 Decrypt with aes in CBC mode
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
120 expanded_key
= key_expansion(key
)
121 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
124 previous_cipher_block
= iv
125 for i
in range(block_count
):
126 block
= data
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
]
127 block
+= [0] * (BLOCK_SIZE_BYTES
- len(block
))
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
)]
134 return decrypted_data
137 def aes_cbc_encrypt(data
, key
, iv
):
139 Encrypt with aes in CBC mode. Using PKCS#7 padding
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
146 expanded_key
= key_expansion(key
)
147 block_count
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
))
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
)
157 encrypted_block
= aes_encrypt(mixed_block
, expanded_key
)
158 encrypted_data
+= encrypted_block
160 previous_cipher_block
= encrypted_block
162 return encrypted_data
165 def aes_gcm_decrypt_and_verify(data
, key
, tag
, nonce
):
167 Decrypt with aes in GBM mode and checks authenticity using tag
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
176 # XXX: check aes, gcm param
178 hash_subkey
= aes_encrypt([0] * BLOCK_SIZE_BYTES
, key_expansion(key
))
181 j0
= nonce
+ [0, 0, 0, 1]
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
)
187 # TODO: add nonce support to aes_ctr_decrypt
189 # nonce_ctr = j0[:12]
192 decrypted_data
= aes_ctr_decrypt(data
, key
, iv_ctr
+ [0] * (BLOCK_SIZE_BYTES
- len(iv_ctr
)))
193 pad_len
= len(data
) // 16 * 16
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
202 if tag
!= aes_ctr_encrypt(s_tag
, key
, j0
):
203 raise ValueError("Mismatching authentication tag")
205 return decrypted_data
208 def aes_encrypt(data
, expanded_key
):
210 Encrypt one block with aes
212 @param {int[]} data 16-Byte state
213 @param {int[]} expanded_key 176/208/240-Byte expanded key
214 @returns {int[]} 16-Byte cipher
216 rounds
= len(expanded_key
) // BLOCK_SIZE_BYTES
- 1
218 data
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
])
219 for i
in range(1, rounds
+ 1):
220 data
= sub_bytes(data
)
221 data
= shift_rows(data
)
223 data
= list(iter_mix_columns(data
, MIX_COLUMN_MATRIX
))
224 data
= xor(data
, expanded_key
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
])
229 def aes_decrypt(data
, expanded_key
):
231 Decrypt one block with aes
233 @param {int[]} data 16-Byte cipher
234 @param {int[]} expanded_key 176/208/240-Byte expanded key
235 @returns {int[]} 16-Byte state
237 rounds
= len(expanded_key
) // BLOCK_SIZE_BYTES
- 1
239 for i
in range(rounds
, 0, -1):
240 data
= xor(data
, expanded_key
[i
* BLOCK_SIZE_BYTES
: (i
+ 1) * BLOCK_SIZE_BYTES
])
242 data
= list(iter_mix_columns(data
, MIX_COLUMN_MATRIX_INV
))
243 data
= shift_rows_inv(data
)
244 data
= sub_bytes_inv(data
)
245 data
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
])
250 def aes_decrypt_text(data
, password
, key_size_bytes
):
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'
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
263 NONCE_LENGTH_BYTES
= 8
265 data
= bytes_to_intlist(compat_b64decode(data
))
266 password
= bytes_to_intlist(password
.encode('utf-8'))
268 key
= password
[:key_size_bytes
] + [0] * (key_size_bytes
- len(password
))
269 key
= aes_encrypt(key
[:BLOCK_SIZE_BYTES
], key_expansion(key
)) * (key_size_bytes
// BLOCK_SIZE_BYTES
)
271 nonce
= data
[:NONCE_LENGTH_BYTES
]
272 cipher
= data
[NONCE_LENGTH_BYTES
:]
274 decrypted_data
= aes_ctr_decrypt(cipher
, key
, nonce
+ [0] * (BLOCK_SIZE_BYTES
- NONCE_LENGTH_BYTES
))
275 plaintext
= intlist_to_bytes(decrypted_data
)
280 RCON
= (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36)
281 SBOX
= (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)
297 SBOX_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)
313 MIX_COLUMN_MATRIX
= ((0x2, 0x3, 0x1, 0x1),
314 (0x1, 0x2, 0x3, 0x1),
315 (0x1, 0x1, 0x2, 0x3),
316 (0x3, 0x1, 0x1, 0x2))
317 MIX_COLUMN_MATRIX_INV
= ((0xE, 0xB, 0xD, 0x9),
318 (0x9, 0xE, 0xB, 0xD),
319 (0xD, 0x9, 0xE, 0xB),
320 (0xB, 0xD, 0x9, 0xE))
321 RIJNDAEL_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)
337 RIJNDAEL_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)
355 def key_expansion(data
):
357 Generate key schedule
359 @param {int[]} data 16/24/32-Byte cipher key
360 @returns {int[]} 176/208/240-Byte expanded key
362 data
= data
[:] # copy
364 key_size_bytes
= len(data
)
365 expanded_key_size_bytes
= (key_size_bytes
// 4 + 7) * BLOCK_SIZE_BYTES
367 while len(data
) < expanded_key_size_bytes
:
369 temp
= key_schedule_core(temp
, rcon_iteration
)
371 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
375 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
377 if key_size_bytes
== 32:
379 temp
= sub_bytes(temp
)
380 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
382 for _
in range(3 if key_size_bytes
== 32 else 2 if key_size_bytes
== 24 else 0):
384 data
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
])
385 data
= data
[:expanded_key_size_bytes
]
397 return [SBOX
[x
] for x
in data
]
400 def sub_bytes_inv(data
):
401 return [SBOX_INV
[x
] for x
in data
]
405 return data
[1:] + [data
[0]]
408 def key_schedule_core(data
, rcon_iteration
):
410 data
= sub_bytes(data
)
411 data
[0] = data
[0] ^ RCON
[rcon_iteration
]
416 def xor(data1
, data2
):
417 return [x ^ y
for x
, y
in zip(data1
, data2
)]
420 def iter_mix_columns(data
, matrix
):
421 for i
in (0, 4, 8, 12):
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])
431 def shift_rows(data
):
432 return [data
[((column
+ row
) & 0b11) * 4 + row
] for column
in range(4) for row
in range(4)]
435 def shift_rows_inv(data
):
436 return [data
[((column
- row
) & 0b11) * 4 + row
] for column
in range(4) for row
in range(4)]
439 def shift_block(data
):
448 data_shifted
.append(n
)
454 data
= data
[:] # copy
455 for i
in range(len(data
) - 1, -1, -1):
459 data
[i
] = data
[i
] + 1
464 def block_product(block_x
, block_y
):
465 # NIST SP 800-38D, Algorithm 1
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
)
470 block_r
= [0xE1] + [0] * (BLOCK_SIZE_BYTES
- 1)
472 block_z
= [0] * BLOCK_SIZE_BYTES
475 for bit
in range(7, -1, -1):
477 block_z
= xor(block_z
, block_v
)
479 do_xor
= block_v
[-1] & 1
480 block_v
= shift_block(block_v
)
482 block_v
= xor(block_v
, block_r
)
487 def ghash(subkey
, data
):
488 # NIST SP 800-38D, Algorithm 2
490 if len(data
) % BLOCK_SIZE_BYTES
:
491 raise ValueError("Length of data should be %d bytes" % BLOCK_SIZE_BYTES
)
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
)
504 'aes_cbc_decrypt_bytes',
507 'aes_gcm_decrypt_and_verify',
508 'aes_gcm_decrypt_and_verify_bytes',