mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Some niceties for the AES implementation
This commit is contained in:
parent
19c1d25c24
commit
9e18735d07
@ -15,6 +15,9 @@ def string_to_bytes_slow(string):
|
|||||||
)
|
)
|
||||||
return ua
|
return ua
|
||||||
|
|
||||||
|
def as_hex(bytes):
|
||||||
|
return [str.format('{:02x}', x) for x in bytes].join(' ')
|
||||||
|
|
||||||
def bytes_to_string_decoder(bytes, offset):
|
def bytes_to_string_decoder(bytes, offset):
|
||||||
offset = offset or 0
|
offset = offset or 0
|
||||||
if offset:
|
if offset:
|
||||||
@ -79,9 +82,8 @@ def convert_to_int32(bytes, output, offset, length):
|
|||||||
class AES:
|
class AES:
|
||||||
|
|
||||||
def __init__(self, key):
|
def __init__(self, key):
|
||||||
self.key = key
|
|
||||||
self.working_mem = [Uint32Array(4), Uint32Array(4)]
|
self.working_mem = [Uint32Array(4), Uint32Array(4)]
|
||||||
rounds = number_of_rounds[self.key.length]
|
rounds = number_of_rounds[key.length]
|
||||||
if not rounds:
|
if not rounds:
|
||||||
raise ValueError('invalid key size (must be length 16, 24 or 32)')
|
raise ValueError('invalid key size (must be length 16, 24 or 32)')
|
||||||
|
|
||||||
@ -96,11 +98,11 @@ class AES:
|
|||||||
self._Kd.push(Uint32Array(4))
|
self._Kd.push(Uint32Array(4))
|
||||||
|
|
||||||
round_key_count = (rounds + 1) * 4
|
round_key_count = (rounds + 1) * 4
|
||||||
KC = self.key.length / 4
|
KC = key.length / 4
|
||||||
|
|
||||||
# convert the key into ints
|
# convert the key into ints
|
||||||
tk = Uint32Array(self.key.length / 4)
|
tk = Uint32Array(KC)
|
||||||
convert_to_int32(self.key, tk)
|
convert_to_int32(key, tk)
|
||||||
|
|
||||||
# copy values into round key arrays
|
# copy values into round key arrays
|
||||||
index = 0
|
index = 0
|
||||||
@ -222,13 +224,18 @@ def generate_key(sz):
|
|||||||
raise ValueError('Invalid key size, must be: 16, 24 or 32')
|
raise ValueError('Invalid key size, must be: 16, 24 or 32')
|
||||||
return random_bytes(sz)
|
return random_bytes(sz)
|
||||||
|
|
||||||
def as_hex(bytes):
|
def generate_tag(sz):
|
||||||
return [str.format('{:02x}', x) for x in bytes].join(' ')
|
return String.fromCharCode.apply(None, random_bytes(sz or 16))
|
||||||
|
|
||||||
class CBC:
|
class CBC:
|
||||||
|
|
||||||
def __init__(self, key):
|
def __init__(self, key):
|
||||||
self.aes = AES(key or generate_key(32))
|
self.key = key or generate_key(32)
|
||||||
|
self.aes = AES(self.key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def key_as_js(self):
|
||||||
|
return '(new Uint8Array(' + JSON.stringify(Array.prototype.slice.call(self.key)) + '))'
|
||||||
|
|
||||||
def encrypt_bytes(self, bytes, tag_bytes):
|
def encrypt_bytes(self, bytes, tag_bytes):
|
||||||
iv = first_iv = random_bytes(16)
|
iv = first_iv = random_bytes(16)
|
||||||
@ -286,6 +293,7 @@ if __name__ == '__main__':
|
|||||||
crypted = cbc.encrypt(text)
|
crypted = cbc.encrypt(text)
|
||||||
decrypted = cbc.decrypt(crypted)
|
decrypted = cbc.decrypt(crypted)
|
||||||
print('Roundtrip:', 'OK' if text is decrypted else 'FAILED')
|
print('Roundtrip:', 'OK' if text is decrypted else 'FAILED')
|
||||||
crypted = cbc.encrypt(text, 'secret-tag')
|
secret_tag = generate_tag()
|
||||||
decrypted = cbc.decrypt(crypted, 'secret-tag')
|
crypted = cbc.encrypt(text, secret_tag)
|
||||||
|
decrypted = cbc.decrypt(crypted, secret_tag)
|
||||||
print('Roundtrip with tag:', 'OK' if text is decrypted else 'FAILED')
|
print('Roundtrip with tag:', 'OK' if text is decrypted else 'FAILED')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user