package main import ( "bytes" "crypto/aes" "encoding/binary" "errors" "flag" "fmt" "io/ioutil" "os/user" "path/filepath" ) /* 0 maybe device ID, not needed to work 1 2 lic name string 3 lic Type "0" 4 lic time "0" 5 */ var keyFile string var deviceId string func initCmdline() { flag.StringVar(&keyFile, "k", "Key.data", "key file") flag.StringVar(&deviceId, "id", "HDO4XXXXXX", "devide Id") flag.Parse() } func Expand(path string) string { if len(path) == 0 || path[0] != '~' { return path } usr, err := user.Current() if err != nil { return path } return filepath.Join(usr.HomeDir, path[1:]) } const delta = 0x9E3779B9 func mx(sum uint32, y uint32, z uint32, p uint32, e uint32, k []uint32) uint32 { return ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum ^ y) + (k[p&3^e] ^ z)) } func fixk(k []uint32) []uint32 { if len(k) < 4 { key := make([]uint32, 4) copy(key, k) return key } return k } func XXTeaEncrypt(v []uint32, k []uint32) []uint32 { length := uint32(len(v)) n := length - 1 k = fixk(k) var y, z, sum, e, p, q uint32 z = v[n] sum = 0 for q = 6 + 52/length; q > 0; q-- { sum += delta e = sum >> 2 & 3 for p = 0; p < n; p++ { y = v[p+1] v[p] += mx(sum, y, z, p, e, k) z = v[p] } y = v[0] v[n] += mx(sum, y, z, p, e, k) z = v[n] } return v } func XXTeaDecrypt(v []uint32, k []uint32) []uint32 { length := uint32(len(v)) n := length - 1 k = fixk(k) var y, z, sum, e, p, q uint32 y = v[0] q = 6 + 52/length for sum = q * delta; sum != 0; sum -= delta { e = sum >> 2 & 3 for p = n; p > 0; p-- { z = v[p-1] v[p] -= mx(sum, y, z, p, e, k) y = v[p] } z = v[n] v[0] -= mx(sum, y, z, p, e, k) y = v[0] } return v } func HexString(data []byte) string { var buf bytes.Buffer for i := 0; i < len(data)-1; i++ { buf.WriteString(fmt.Sprintf("%02X ", data[i])) } buf.WriteString(fmt.Sprintf("%02X", data[len(data)-1])) return buf.String() } func HexStringS(data []byte, sep string) string { var buf bytes.Buffer for i := 0; i < len(data)-1; i++ { buf.WriteString(fmt.Sprintf("%02X%s", data[i], sep)) } buf.WriteString(fmt.Sprintf("%02X", data[len(data)-1])) return buf.String() } func HexStringLsb(data []byte, sep string) string { var buf bytes.Buffer for i := 0; i < len(data)-1; i++ { buf.WriteString(fmt.Sprintf("%02x%s", (data[i]<<4)|(data[i]>>4), sep)) } t := data[len(data)-1] buf.WriteString(fmt.Sprintf("%02x", (t<<4)|(t>>4))) return buf.String() } func decodeDefaultXXTEA(data []byte) []byte { k := []uint32{0x03920001, 0x08410841, 0x18C32104, 0x318639C7} N := len(data) u32 := make([]uint32, N>>2) for i, _ := range u32 { u32[i] = binary.LittleEndian.Uint32(data[i*4:]) } u32d := XXTeaDecrypt(u32, k) res := make([]uint8, N) for i, v := range u32d { binary.LittleEndian.PutUint32(res[i*4:], v) } return res } func EncryptLicenseString(key []uint8, str string) (string, error) { block, err := aes.NewCipher(key) if nil != err { return "", err } x := make([]uint8, 48) copy(x, []uint8(str)) block.Encrypt(x, x) block.Encrypt(x[0x10:], x[0x10:]) block.Encrypt(x[0x20:], x[0x20:]) return HexStringLsb(x, ""), nil } func MakeLicense(key []uint8, deviceId, feature string) string { s := fmt.Sprintf("%s#0#%s#4#0#0", deviceId, feature) res, err := EncryptLicenseString(key, s) if nil != err { return "" } return fmt.Sprintf("HDO4000-%s@%s", feature, res) } func LoadKeys() ([]uint8, error) { data, err := ioutil.ReadFile(Expand(keyFile)) if nil != err { return nil, err } dd := decodeDefaultXXTEA(data) i := bytes.Index(dd, []uint8(";")) if -1 == i { return nil, errors.New("key format error") } fmt.Printf("Key: %v\n", string(dd)) return dd[i+1:], nil } // BND // MSO // COMP // EMBD // AUTO // FLEX // AUDIO // AERO // ARINC // DG // JITTER // EYE // RTSA // CM_USB // CM_ENET // CM_IPI // CM_HDMI // PWR // UPA // RLU // BODE // BW7T10 // BW7T20 // BW100T20 // BW2T4 // BW2T8 // BW4T8 // COUNT // UNKNOWN var options []string = []string{"EMBD", "AUTO", "BW2T8", "COMP", "AERO", "FLEX", "AUDIO", "RLU", "UPA"} func main() { initCmdline() k, err := LoadKeys() if nil != err { fmt.Printf("error %v\n", err) return } fmt.Printf("Generating options for %s\n", deviceId) for _, o := range options { lic := MakeLicense(k[0:32], deviceId, o) fmt.Printf(":SYST:OPT:INST %v\n", lic) } }