import argparse
import base64
import binascii
import zlib
import hmac
import hashlib
import struct
from Crypto.Cipher import AES
# obtain values from /usr/local/lib/libfts_license.so.1.12.1
# Note that in python, you enter binary hex values as b"\x0d\x0e..."
HMAC_KEY = b""
HMAC_MSG = b"" * 4
AES_IV = b""
def init_lookup_table():
out = []
for i in range(0x100):
lookup_table_entry = i << 0x18
for k in range(8):
if lookup_table_entry >> 31:
inlr = lookup_table_entry << 1
if lookup_table_entry >> 31:
lookup_table_entry = inlr ^ 0x4c11db7
else:
lookup_table_entry = lookup_table_entry << 1
lookup_table_entry &= 0xffffffff
out.append(lookup_table_entry)
return out
def spd_crc32(param_1, x):
tbl = init_lookup_table()
for pbVar1 in param_1:
x = (tbl[(pbVar1 ^ x >> 0x18) & 0xff] ^ x << 8) & 0xffffffff
return x
def simple_generator(ext_features, type, serial):
if ext_features.lower() == "kvm":
features = b"\x01\x00\x00\x00"
elif ext_features.lower() == "kvm_media":
features = b"\x03\x00\x00\x00"
elif ext_features.lower() == "kvm_media_elcm":
# this license type doesn't validate on my TX chassis
# but apparently works on RX chassis
if type.lower() == "tx":
print("License may not be valid for TX chassis with eLCM enabled")
features = b"\x0f\x00\x00\x00"
return license_generator(serial, features, type.lower())
def license_generator(serial, features, type):
# chassis type TX
struct_data = 0xffffff00
if type == "rx":
# chassis type RX
struct_data = 0xffffff05
DATA = b'iRMC' \
+ features \
+ struct.pack('>I', struct_data) + \
struct.pack('<I', spd_crc32(serial.encode("ASCII"), 1))
print(binascii.hexlify(DATA).decode('utf-8'))
aes_key = hmac.new(HMAC_KEY, HMAC_MSG, hashlib.sha1).digest()
# this is AES-128, so only take the first 16 bytes of the aes_key
cipher = AES.new(aes_key[:16], AES.MODE_CBC, iv=AES_IV)
encrypted_license = cipher.encrypt(DATA)
encoded_license = base64.b32encode(encrypted_license)
license = encoded_license.decode("UTF-8").replace("=","")
return '-'.join(license[i:i+4] for i in range(0, len(license), 4))
if __name__ == "__main__":
if len(HMAC_KEY) != 16 or len(HMAC_MSG) != 16*4 or len(AES_IV) != 16:
print("You are missing the HMAC and AES values")
else:
print(simple_generator("kvm_media", "rx", "YV3R002727"))