def test_vectors_rfc5228_ctr(n, vector_and_counter): vector = vector_and_counter[0] key, nonce, iv = map(binascii.unhexlify, (vector.key, vector.nonce, vector.iv)) cipher = camellia.new(key, mode=camellia.MODE_CTR, counter=Counter(nonce, iv)) plain_bytes = binascii.unhexlify(vector.plain) cipher_bytes = binascii.unhexlify(vector.cipher) cipher_result = binascii.hexlify( cipher.encrypt(plain_bytes)).decode().upper() cipher = camellia.new(key, mode=camellia.MODE_CTR, counter=Counter(nonce, iv)) plain_result = binascii.hexlify( cipher.decrypt(cipher_bytes)).decode().upper() assert cipher_result == vector.cipher assert plain_result == vector.plain
def decrypt(password: str, encrypted: str) -> bytes: encoded_salt, rounds, encoded_iv_cipher, encoded_mac = encrypted.split(".") rounds = int(rounds) # Generate key key = hashlib.pbkdf2_hmac(PBKDF_HASH, password.encode(), base64.b64decode(encoded_salt), rounds, dklen=64) key_encryption, key_authentication = key[:32], key[32:] iv_cipher = base64.b64decode(encoded_iv_cipher) # Compare in time-safe manner, to prevent an attacker learning # about the newly computed MAC. if not hmac.compare_digest( hmac.new(key_authentication, iv_cipher, HMAC_ALGO).digest(), base64.b64decode(encoded_mac)): raise ValueError("mac does not match, invalid password or data") iv, cipher_text = iv_cipher[:16], iv_cipher[16:] decrypter = camellia.new(key_encryption, mode=camellia.MODE_CBC, IV=iv) # Decrypt and remove padding return _unpad(decrypter.decrypt(cipher_text))
def encrypt(password: str, plaintext: bytes) -> str: salt = os.urandom(16) # Random salt each time # Derive key from password, to compensate weaker passwords key = hashlib.pbkdf2_hmac(PBKDF_HASH, password.encode(), salt, PBKDF_ROUNDS, dklen=64) # Use individual keys for encryption and authentication key_encryption, key_authentication = key[:32], key[32:] iv = os.urandom(16) # Random IV, this is important encrypter = camellia.new(key_encryption, camellia.MODE_CBC, IV=iv) # The data is padded with PKCS#5 cipher_text = encrypter.encrypt(_pad(plaintext)) # Authentication tag mac = hmac.new(key_authentication, iv + cipher_text, HMAC_ALGO).digest() # Rounds are serialized to potentially increase it for new files return "{}.{}.{}.{}".format( base64.b64encode(salt).decode(), PBKDF_ROUNDS, base64.b64encode(iv + cipher_text).decode(), base64.b64encode(mac).decode())
def test_vectors_ntt(vector): key = binascii.unhexlify(vector.key) plain = binascii.unhexlify(vector.plain) cipher = binascii.unhexlify(vector.cipher) cam = camellia.new(key, camellia.MODE_ECB) cipher_result = cam.encrypt(plain) plain_result = cam.decrypt(cipher) assert cipher_result == cipher assert plain_result == plain
def test_vectors_openssl(lineno, vector): mode = vector.mode key, iv, plain_text, cipher_text = map( binascii.unhexlify, (vector.key, vector.iv or b'00' * 16, vector.plain, vector.cipher)) if mode == "ECB": iv = None cipher_kwargs = dict(key=key, mode=MODES[mode]) if mode != "ECB": cipher_kwargs["IV"] = iv if mode == "CFB": cipher_kwargs["segment_size"] = 128 if vector.encdec in (ACTION_ENCRYPT, ACTION_BOTH): cipher = camellia.new(**cipher_kwargs) assert cipher.encrypt(plain_text) == cipher_text if vector.encdec in (ACTION_DECRYPT, ACTION_BOTH): cipher = camellia.new(**cipher_kwargs) assert cipher.decrypt(cipher_text) == plain_text
def test_vectors_nessie(name, vector): (key, plain, cipher, decrypted, i100, i1000) = map( binascii.unhexlify, vector[1:]) cam = camellia.new(key, camellia.MODE_ECB) cipher_result = cam.encrypt(plain) decrypted_result = cam.decrypt(cipher) i100_result = plain for i in range(100): i100_result = cam.encrypt(i100_result) i1000_result = plain for i in range(1000): i1000_result = cam.encrypt(i1000_result) assert cipher == cipher_result assert decrypted == decrypted_result assert i100 == i100_result assert i1000 == i1000_result
#pip install python-camellia import camellia #by binary analysis data_key = b"\xEB\x5E\xB3\xCA\x92\xA1\xFF\x01\x80\x4E\x36\x58\x56\xAD\x9E\xB7" code_key = b"\xCC\x7C\x3E\xE0\xA5\x62\x42\x62\xEB\x1C\xBD\x84\x4A\xC1\xCF\x51" server_key = b"\xff\xd3\x30\xb7\x07\x00\x00\x00activate" data_key = camellia.new(server_key, mode=camellia.MODE_ECB).decrypt(data_key) code_key = camellia.new(data_key, mode=camellia.MODE_ECB).decrypt(code_key) data_key = camellia.new(code_key, mode=camellia.MODE_ECB).decrypt(data_key) print("[+] data_key = {}({})".format(data_key,data_key.hex())) print("[+] code_key = {}({})".format(code_key,code_key.hex())) #by binary analysis with open("./data_enc.o","rb") as f: data_enc = f.read() with open("./code_enc.o","rb") as f: code_enc = f.read() with open("./data.o","wb") as f: data = camellia.new(data_key, mode=camellia.MODE_ECB).decrypt(data_enc) f.write(data) with open("./code.o","wb") as f: f.write(camellia.new(code_key, mode=camellia.MODE_ECB).decrypt(code_enc)) #by bootstrap analysis data_decode = data[:0x30] + bytes([byte ^ 0xf4 for byte in data[0x30:0xe0]]) + data[0xe0:]
def decrypt(buf, n, key): buf = rotate_buffer(buf, n) cp = camellia.new(key, camellia.MODE_ECB) buf = cp.decrypt(buf) return buf