]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/aes.py
5efd0f836bcf2375b065be008a36e5b8a54d2e69
   1 from __future__ 
import unicode_literals
 
   3 __all__ 
= ['aes_encrypt', 'key_expansion', 'aes_ctr_decrypt', 'aes_cbc_decrypt', 'aes_decrypt_text'] 
   8 from .utils 
import bytes_to_intlist
, intlist_to_bytes
 
  13 def aes_ctr_decrypt(data
, key
, counter
): 
  15     Decrypt with aes in counter mode 
  17     @param {int[]} data        cipher 
  18     @param {int[]} key         16/24/32-Byte cipher key 
  19     @param {instance} counter  Instance whose next_value function (@returns {int[]}  16-Byte block) 
  20                                returns the next counter block 
  21     @returns {int[]}           decrypted data 
  23     expanded_key 
= key_expansion(key
) 
  24     block_count 
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
)) 
  27     for i 
in range(block_count
): 
  28         counter_block 
= counter
.next_value() 
  29         block 
= data
[i 
* BLOCK_SIZE_BYTES
: (i 
+ 1) * BLOCK_SIZE_BYTES
] 
  30         block 
+= [0] * (BLOCK_SIZE_BYTES 
- len(block
)) 
  32         cipher_counter_block 
= aes_encrypt(counter_block
, expanded_key
) 
  33         decrypted_data 
+= xor(block
, cipher_counter_block
) 
  34     decrypted_data 
= decrypted_data
[:len(data
)] 
  39 def aes_cbc_decrypt(data
, key
, iv
): 
  41     Decrypt with aes in CBC mode 
  43     @param {int[]} data        cipher 
  44     @param {int[]} key         16/24/32-Byte cipher key 
  45     @param {int[]} iv          16-Byte IV 
  46     @returns {int[]}           decrypted data 
  48     expanded_key 
= key_expansion(key
) 
  49     block_count 
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
)) 
  52     previous_cipher_block 
= iv
 
  53     for i 
in range(block_count
): 
  54         block 
= data
[i 
* BLOCK_SIZE_BYTES
: (i 
+ 1) * BLOCK_SIZE_BYTES
] 
  55         block 
+= [0] * (BLOCK_SIZE_BYTES 
- len(block
)) 
  57         decrypted_block 
= aes_decrypt(block
, expanded_key
) 
  58         decrypted_data 
+= xor(decrypted_block
, previous_cipher_block
) 
  59         previous_cipher_block 
= block
 
  60     decrypted_data 
= decrypted_data
[:len(data
)] 
  65 def key_expansion(data
): 
  69     @param {int[]} data  16/24/32-Byte cipher key 
  70     @returns {int[]}     176/208/240-Byte expanded key 
  74     key_size_bytes 
= len(data
) 
  75     expanded_key_size_bytes 
= (key_size_bytes 
// 4 + 7) * BLOCK_SIZE_BYTES
 
  77     while len(data
) < expanded_key_size_bytes
: 
  79         temp 
= key_schedule_core(temp
, rcon_iteration
) 
  81         data 
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
]) 
  85             data 
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
]) 
  87         if key_size_bytes 
== 32: 
  89             temp 
= sub_bytes(temp
) 
  90             data 
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
]) 
  92         for _ 
in range(3 if key_size_bytes 
== 32 else 2 if key_size_bytes 
== 24 else 0): 
  94             data 
+= xor(temp
, data
[-key_size_bytes
: 4 - key_size_bytes
]) 
  95     data 
= data
[:expanded_key_size_bytes
] 
 100 def aes_encrypt(data
, expanded_key
): 
 102     Encrypt one block with aes 
 104     @param {int[]} data          16-Byte state 
 105     @param {int[]} expanded_key  176/208/240-Byte expanded key 
 106     @returns {int[]}             16-Byte cipher 
 108     rounds 
= len(expanded_key
) // BLOCK_SIZE_BYTES 
- 1 
 110     data 
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
]) 
 111     for i 
in range(1, rounds 
+ 1): 
 112         data 
= sub_bytes(data
) 
 113         data 
= shift_rows(data
) 
 115             data 
= mix_columns(data
) 
 116         data 
= xor(data
, expanded_key
[i 
* BLOCK_SIZE_BYTES
: (i 
+ 1) * BLOCK_SIZE_BYTES
]) 
 121 def aes_decrypt(data
, expanded_key
): 
 123     Decrypt one block with aes 
 125     @param {int[]} data          16-Byte cipher 
 126     @param {int[]} expanded_key  176/208/240-Byte expanded key 
 127     @returns {int[]}             16-Byte state 
 129     rounds 
= len(expanded_key
) // BLOCK_SIZE_BYTES 
- 1 
 131     for i 
in range(rounds
, 0, -1): 
 132         data 
= xor(data
, expanded_key
[i 
* BLOCK_SIZE_BYTES
: (i 
+ 1) * BLOCK_SIZE_BYTES
]) 
 134             data 
= mix_columns_inv(data
) 
 135         data 
= shift_rows_inv(data
) 
 136         data 
= sub_bytes_inv(data
) 
 137     data 
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
]) 
 142 def aes_decrypt_text(data
, password
, key_size_bytes
): 
 145     - The first 8 Bytes of decoded 'data' are the 8 high Bytes of the counter 
 146     - The cipher key is retrieved by encrypting the first 16 Byte of 'password' 
 147       with the first 'key_size_bytes' Bytes from 'password' (if necessary filled with 0's) 
 148     - Mode of operation is 'counter' 
 150     @param {str} data                    Base64 encoded string 
 151     @param {str,unicode} password        Password (will be encoded with utf-8) 
 152     @param {int} key_size_bytes          Possible values: 16 for 128-Bit, 24 for 192-Bit or 32 for 256-Bit 
 153     @returns {str}                       Decrypted data 
 155     NONCE_LENGTH_BYTES 
= 8 
 157     data 
= bytes_to_intlist(base64
.b64decode(data
)) 
 158     password 
= bytes_to_intlist(password
.encode('utf-8')) 
 160     key 
= password
[:key_size_bytes
] + [0] * (key_size_bytes 
- len(password
)) 
 161     key 
= aes_encrypt(key
[:BLOCK_SIZE_BYTES
], key_expansion(key
)) * (key_size_bytes 
// BLOCK_SIZE_BYTES
) 
 163     nonce 
= data
[:NONCE_LENGTH_BYTES
] 
 164     cipher 
= data
[NONCE_LENGTH_BYTES
:] 
 167         __value 
= nonce 
+ [0] * (BLOCK_SIZE_BYTES 
- NONCE_LENGTH_BYTES
) 
 169         def next_value(self
): 
 171             self
.__value 
= inc(self
.__value
) 
 174     decrypted_data 
= aes_ctr_decrypt(cipher
, key
, Counter()) 
 175     plaintext 
= intlist_to_bytes(decrypted_data
) 
 179 RCON 
= (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36) 
 180 SBOX 
= (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 
 181         0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 
 182         0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 
 183         0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 
 184         0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 
 185         0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 
 186         0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 
 187         0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 
 188         0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 
 189         0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 
 190         0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 
 191         0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 
 192         0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 
 193         0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 
 194         0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 
 195         0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16) 
 196 SBOX_INV 
= (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 
 197             0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 
 198             0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 
 199             0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 
 200             0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 
 201             0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 
 202             0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 
 203             0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 
 204             0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 
 205             0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 
 206             0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 
 207             0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 
 208             0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 
 209             0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 
 210             0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 
 211             0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d) 
 212 MIX_COLUMN_MATRIX 
= ((0x2, 0x3, 0x1, 0x1), 
 213                      (0x1, 0x2, 0x3, 0x1), 
 214                      (0x1, 0x1, 0x2, 0x3), 
 215                      (0x3, 0x1, 0x1, 0x2)) 
 216 MIX_COLUMN_MATRIX_INV 
= ((0xE, 0xB, 0xD, 0x9), 
 217                          (0x9, 0xE, 0xB, 0xD), 
 218                          (0xD, 0x9, 0xE, 0xB), 
 219                          (0xB, 0xD, 0x9, 0xE)) 
 220 RIJNDAEL_EXP_TABLE 
= (0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35, 
 221                       0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, 
 222                       0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31, 
 223                       0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, 
 224                       0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88, 
 225                       0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, 
 226                       0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3, 
 227                       0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, 
 228                       0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41, 
 229                       0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, 
 230                       0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, 
 231                       0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54, 
 232                       0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, 
 233                       0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E, 
 234                       0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, 
 235                       0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01) 
 236 RIJNDAEL_LOG_TABLE 
= (0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03, 
 237                       0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1, 
 238                       0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78, 
 239                       0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e, 
 240                       0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38, 
 241                       0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10, 
 242                       0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba, 
 243                       0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57, 
 244                       0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8, 
 245                       0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0, 
 246                       0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7, 
 247                       0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d, 
 248                       0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1, 
 249                       0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab, 
 250                       0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5, 
 251                       0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07) 
 255     return [SBOX
[x
] for x 
in data
] 
 258 def sub_bytes_inv(data
): 
 259     return [SBOX_INV
[x
] for x 
in data
] 
 263     return data
[1:] + [data
[0]] 
 266 def key_schedule_core(data
, rcon_iteration
): 
 268     data 
= sub_bytes(data
) 
 269     data
[0] = data
[0] ^ RCON
[rcon_iteration
] 
 274 def xor(data1
, data2
): 
 275     return [x ^ y 
for x
, y 
in zip(data1
, data2
)] 
 278 def rijndael_mul(a
, b
): 
 279     if(a 
== 0 or b 
== 0): 
 281     return RIJNDAEL_EXP_TABLE
[(RIJNDAEL_LOG_TABLE
[a
] + RIJNDAEL_LOG_TABLE
[b
]) % 0xFF] 
 284 def mix_column(data
, matrix
): 
 288         for column 
in range(4): 
 290             mixed ^
= rijndael_mul(data
[column
], matrix
[row
][column
]) 
 291         data_mixed
.append(mixed
) 
 295 def mix_columns(data
, matrix
=MIX_COLUMN_MATRIX
): 
 298         column 
= data
[i 
* 4: (i 
+ 1) * 4] 
 299         data_mixed 
+= mix_column(column
, matrix
) 
 303 def mix_columns_inv(data
): 
 304     return mix_columns(data
, MIX_COLUMN_MATRIX_INV
) 
 307 def shift_rows(data
): 
 309     for column 
in range(4): 
 311             data_shifted
.append(data
[((column 
+ row
) & 0b11) * 4 + row
]) 
 315 def shift_rows_inv(data
): 
 317     for column 
in range(4): 
 319             data_shifted
.append(data
[((column 
- row
) & 0b11) * 4 + row
]) 
 324     data 
= data
[:]  # copy 
 325     for i 
in range(len(data
) - 1, -1, -1): 
 329             data
[i
] = data
[i
] + 1