LyoKICogQ29weXJpZ2h0IChjKSAyMDAyIEp1aGEgWXJq9mzkLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogQ29weXJpZ2h0IChjKSAyMDAxIE1hcmt1cyBGcmllZGwuCiAqIAogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTUyBPUgogKiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwKICogSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUCiAqIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GCiAqIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqLwoKI2luY2x1ZGUgImluY2x1ZGVzLmgiCiNpZiBkZWZpbmVkKFNNQVJUQ0FSRCkgJiYgZGVmaW5lZChVU0VfT1BFTlNDKQoKI2luY2x1ZGUgPG9wZW5zc2wvZXZwLmg+CiNpbmNsdWRlIDxvcGVuc3NsL3g1MDkuaD4KCiNpbmNsdWRlIDxvcGVuc2Mvb3BlbnNjLmg+CiNpbmNsdWRlIDxvcGVuc2MvcGtjczE1Lmg+CgojaW5jbHVkZSAia2V5LmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgInJlYWRwYXNzLmgiCiNpbmNsdWRlICJzY2FyZC5oIgoKI2lmIE9QRU5TU0xfVkVSU0lPTl9OVU1CRVIgPCAweDAwOTA3MDAwTCAmJiBkZWZpbmVkKENSWVBUT19MT0NLX0VOR0lORSkKI2RlZmluZSBVU0VfRU5HSU5FCiNkZWZpbmUgUlNBX2dldF9kZWZhdWx0X21ldGhvZCBSU0FfZ2V0X2RlZmF1bHRfb3BlbnNzbF9tZXRob2QKI2Vsc2UKI2VuZGlmCgojaWZkZWYgVVNFX0VOR0lORQojaW5jbHVkZSA8b3BlbnNzbC9lbmdpbmUuaD4KI2RlZmluZSBzY19nZXRfcnNhIHNjX2dldF9lbmdpbmUKI2Vsc2UKI2RlZmluZSBzY19nZXRfcnNhIHNjX2dldF9yc2FfbWV0aG9kCiNlbmRpZgoKc3RhdGljIGludCBzY19yZWFkZXJfaWQ7CnN0YXRpYyBzY19jb250ZXh0X3QgKmN0eCA9IE5VTEw7CnN0YXRpYyBzY19jYXJkX3QgKmNhcmQgPSBOVUxMOwpzdGF0aWMgc2NfcGtjczE1X2NhcmRfdCAqcDE1Y2FyZCA9IE5VTEw7CgpzdGF0aWMgY2hhciAqc2NfcGluID0gTlVMTDsKCnN0cnVjdCBzY19wcml2X2RhdGEKewoJc3RydWN0IHNjX3BrY3MxNV9pZCBjZXJ0X2lkOwoJaW50IHJlZl9jb3VudDsKfTsKCnZvaWQKc2NfY2xvc2Uodm9pZCkKewoJaWYgKHAxNWNhcmQpIHsKCQlzY19wa2NzMTVfdW5iaW5kKHAxNWNhcmQpOwoJCXAxNWNhcmQgPSBOVUxMOwoJfQoJaWYgKGNhcmQpIHsKCQlzY19kaXNjb25uZWN0X2NhcmQoY2FyZCwgMCk7CgkJY2FyZCA9IE5VTEw7Cgl9CglpZiAoY3R4KSB7CgkJc2NfcmVsZWFzZV9jb250ZXh0KGN0eCk7CgkJY3R4ID0gTlVMTDsKCX0KfQoKc3RhdGljIGludCAKc2NfaW5pdCh2b2lkKQp7CglpbnQgcjsKCglyID0gc2NfZXN0YWJsaXNoX2NvbnRleHQoJmN0eCwgIm9wZW5zc2giKTsKCWlmIChyKQoJCWdvdG8gZXJyOwoJciA9IHNjX2Nvbm5lY3RfY2FyZChjdHgtPnJlYWRlcltzY19yZWFkZXJfaWRdLCAwLCAmY2FyZCk7CglpZiAocikKCQlnb3RvIGVycjsKCXIgPSBzY19wa2NzMTVfYmluZChjYXJkLCAmcDE1Y2FyZCk7CglpZiAocikKCQlnb3RvIGVycjsKCXJldHVybiAwOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIHI7Cn0KCi8qIHByaXZhdGUga2V5IG9wZXJhdGlvbnMgKi8KCnN0YXRpYyBpbnQKc2NfcHJrZXlfb3BfaW5pdChSU0EgKnJzYSwgc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKiprZXlfb2JqX291dCkKewoJaW50IHI7CglzdHJ1Y3Qgc2NfcHJpdl9kYXRhICpwcml2OwoJc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKmtleV9vYmo7CglzdHJ1Y3Qgc2NfcGtjczE1X3Bya2V5X2luZm8gKmtleTsKCXN0cnVjdCBzY19wa2NzMTVfb2JqZWN0ICpwaW5fb2JqOwoJc3RydWN0IHNjX3BrY3MxNV9waW5faW5mbyAqcGluOwoKCXByaXYgPSAoc3RydWN0IHNjX3ByaXZfZGF0YSAqKSBSU0FfZ2V0X2FwcF9kYXRhKHJzYSk7CglpZiAocHJpdiA9PSBOVUxMKQoJCXJldHVybiAtMTsKCWlmIChwMTVjYXJkID09IE5VTEwpIHsKCQlzY19jbG9zZSgpOwoJCXIgPSBzY19pbml0KCk7CgkJaWYgKHIpIHsKCQkJZXJyb3IoIlNtYXJ0Q2FyZCBpbml0IGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCX0KCXIgPSBzY19wa2NzMTVfZmluZF9wcmtleV9ieV9pZChwMTVjYXJkLCAmcHJpdi0+Y2VydF9pZCwgJmtleV9vYmopOwoJaWYgKHIpIHsKCQllcnJvcigiVW5hYmxlIHRvIGZpbmQgcHJpdmF0ZSBrZXkgZnJvbSBTbWFydENhcmQ6ICVzIiwKCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9CglrZXkgPSBrZXlfb2JqLT5kYXRhOwoJciA9IHNjX3BrY3MxNV9maW5kX3Bpbl9ieV9hdXRoX2lkKHAxNWNhcmQsICZrZXlfb2JqLT5hdXRoX2lkLAoJCQkJCSAgJnBpbl9vYmopOwoJaWYgKHIgPT0gU0NfRVJST1JfT0JKRUNUX05PVF9GT1VORCkgewoJCS8qIG5vIHBpbiByZXF1aXJlZCAqLwoJCSprZXlfb2JqX291dCA9IGtleV9vYmo7CgkJcmV0dXJuIDA7Cgl9IGVsc2UgaWYgKHIpIHsKCQllcnJvcigiVW5hYmxlIHRvIGZpbmQgUElOIG9iamVjdCBmcm9tIFNtYXJ0Q2FyZDogJXMiLAoJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQlnb3RvIGVycjsKCX0KCXBpbiA9IHBpbl9vYmotPmRhdGE7CglyID0gc2NfbG9jayhjYXJkKTsKCWlmIChyKSB7CgkJZXJyb3IoIlVuYWJsZSB0byBsb2NrIHNtYXJ0Y2FyZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9CglpZiAoc2NfcGluICE9IE5VTEwpIHsKCQlyID0gc2NfcGtjczE1X3ZlcmlmeV9waW4ocDE1Y2FyZCwgcGluLCBzY19waW4sCgkJCQkJIHN0cmxlbihzY19waW4pKTsKCQlpZiAocikgewoJCQlzY191bmxvY2soY2FyZCk7CgkJCWVycm9yKCJQSU4gY29kZSB2ZXJpZmljYXRpb24gZmFpbGVkOiAlcyIsCgkJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQkJZ290byBlcnI7CgkJfQoJfQoJKmtleV9vYmpfb3V0ID0ga2V5X29iajsKCXJldHVybiAwOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50CnNjX3ByaXZhdGVfZGVjcnlwdChpbnQgZmxlbiwgdV9jaGFyICpmcm9tLCB1X2NoYXIgKnRvLCBSU0EgKnJzYSwKICAgIGludCBwYWRkaW5nKQp7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCWludCByOwoKCWlmIChwYWRkaW5nICE9IFJTQV9QS0NTMV9QQURESU5HKQoJCXJldHVybiAtMTsJCglyID0gc2NfcHJrZXlfb3BfaW5pdChyc2EsICZrZXlfb2JqKTsKCWlmIChyKQoJCXJldHVybiAtMTsKCXIgPSBzY19wa2NzMTVfZGVjaXBoZXIocDE1Y2FyZCwga2V5X29iaiwgU0NfQUxHT1JJVEhNX1JTQV9QQURfUEtDUzEsIAoJICAgIGZyb20sIGZsZW4sIHRvLCBmbGVuKTsKCXNjX3VubG9jayhjYXJkKTsKCWlmIChyIDwgMCkgewoJCWVycm9yKCJzY19wa2NzMTVfZGVjaXBoZXIoKSBmYWlsZWQ6ICVzIiwgc2Nfc3RyZXJyb3IocikpOwoJCWdvdG8gZXJyOwoJfQoJcmV0dXJuIHI7CmVycjoKCXNjX2Nsb3NlKCk7CglyZXR1cm4gLTE7Cn0KCnN0YXRpYyBpbnQKc2Nfc2lnbihpbnQgdHlwZSwgdV9jaGFyICptLCB1bnNpZ25lZCBpbnQgbV9sZW4sCgl1bnNpZ25lZCBjaGFyICpzaWdyZXQsIHVuc2lnbmVkIGludCAqc2lnbGVuLCBSU0EgKnJzYSkKewoJc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKmtleV9vYmo7CglpbnQgcjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3MgPSAwOwoKCXIgPSBzY19wcmtleV9vcF9pbml0KHJzYSwgJmtleV9vYmopOwoJaWYgKHIpCgkJcmV0dXJuIC0xOwoJLyogRklYTUU6IGxlbmd0aCBvZiBzaWdyZXQgY29ycmVjdD8gKi8KCS8qIEZJWE1FOiBjaGVjayAndHlwZScgYW5kIG1vZGlmeSBmbGFncyBhY2NvcmRpbmdseSAqLwoJZmxhZ3MgPSBTQ19BTEdPUklUSE1fUlNBX1BBRF9QS0NTMSB8IFNDX0FMR09SSVRITV9SU0FfSEFTSF9TSEExOwoJciA9IHNjX3BrY3MxNV9jb21wdXRlX3NpZ25hdHVyZShwMTVjYXJkLCBrZXlfb2JqLCBmbGFncywKCQkJCQltLCBtX2xlbiwgc2lncmV0LCBSU0Ffc2l6ZShyc2EpKTsKCXNjX3VubG9jayhjYXJkKTsKCWlmIChyIDwgMCkgewoJCWVycm9yKCJzY19wa2NzMTVfY29tcHV0ZV9zaWduYXR1cmUoKSBmYWlsZWQ6ICVzIiwKCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9Cgkqc2lnbGVuID0gcjsKCXJldHVybiAxOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKc2NfcHJpdmF0ZV9lbmNyeXB0KGludCBmbGVuLCB1X2NoYXIgKmZyb20sIHVfY2hhciAqdG8sIFJTQSAqcnNhLAogICAgaW50IHBhZGRpbmcpCnsKCWVycm9yKCJQcml2YXRlIGtleSBlbmNyeXB0aW9uIG5vdCBzdXBwb3J0ZWQiKTsKCXJldHVybiAtMTsKfQoKLyogY2FsbGVkIG9uIGZyZWUgKi8KCnN0YXRpYyBpbnQgKCpvcmlnX2ZpbmlzaCkoUlNBICpyc2EpID0gTlVMTDsKCnN0YXRpYyBpbnQKc2NfZmluaXNoKFJTQSAqcnNhKQp7CglzdHJ1Y3Qgc2NfcHJpdl9kYXRhICpwcml2OwoKCXByaXYgPSBSU0FfZ2V0X2FwcF9kYXRhKHJzYSk7Cglwcml2LT5yZWZfY291bnQtLTsKCWlmIChwcml2LT5yZWZfY291bnQgPT0gMCkgewoJCWZyZWUocHJpdik7CgkJc2NfY2xvc2UoKTsKCX0KCWlmIChvcmlnX2ZpbmlzaCkKCQlvcmlnX2ZpbmlzaChyc2EpOwoJcmV0dXJuIDE7Cn0KCi8qIGVuZ2luZSBmb3Igb3ZlcmxvYWRpbmcgcHJpdmF0ZSBrZXkgb3BlcmF0aW9ucyAqLwoKc3RhdGljIFJTQV9NRVRIT0QgKgpzY19nZXRfcnNhX21ldGhvZCh2b2lkKQp7CglzdGF0aWMgUlNBX01FVEhPRCBzbWFydF9yc2E7Cgljb25zdCBSU0FfTUVUSE9EICpkZWYgPSBSU0FfZ2V0X2RlZmF1bHRfbWV0aG9kKCk7CgoJLyogdXNlIHRoZSBPcGVuU1NMIHZlcnNpb24gKi8KCW1lbWNweSgmc21hcnRfcnNhLCBkZWYsIHNpemVvZihzbWFydF9yc2EpKTsKCglzbWFydF9yc2EubmFtZQkJPSAib3BlbnNjIjsKCgkvKiBvdmVybG9hZCAqLwoJc21hcnRfcnNhLnJzYV9wcml2X2VuYwk9IHNjX3ByaXZhdGVfZW5jcnlwdDsKCXNtYXJ0X3JzYS5yc2FfcHJpdl9kZWMJPSBzY19wcml2YXRlX2RlY3J5cHQ7CglzbWFydF9yc2EucnNhX3NpZ24JPSBzY19zaWduOwoKCS8qIHNhdmUgb3JpZ2luYWwgKi8KCW9yaWdfZmluaXNoCQk9IGRlZi0+ZmluaXNoOwoJc21hcnRfcnNhLmZpbmlzaAk9IHNjX2ZpbmlzaDsKCglyZXR1cm4gJnNtYXJ0X3JzYTsKfQoKI2lmZGVmIFVTRV9FTkdJTkUKc3RhdGljIEVOR0lORSAqCnNjX2dldF9lbmdpbmUodm9pZCkKewoJc3RhdGljIEVOR0lORSAqc21hcnRfZW5naW5lID0gTlVMTDsKCglpZiAoKHNtYXJ0X2VuZ2luZSA9IEVOR0lORV9uZXcoKSkgPT0gTlVMTCkKCQlmYXRhbCgiRU5HSU5FX25ldyBmYWlsZWQiKTsKCglFTkdJTkVfc2V0X2lkKHNtYXJ0X2VuZ2luZSwgIm9wZW5zYyIpOwoJRU5HSU5FX3NldF9uYW1lKHNtYXJ0X2VuZ2luZSwgIk9wZW5TQyIpOwoKCUVOR0lORV9zZXRfUlNBKHNtYXJ0X2VuZ2luZSwgc2NfZ2V0X3JzYV9tZXRob2QoKSk7CglFTkdJTkVfc2V0X0RTQShzbWFydF9lbmdpbmUsIERTQV9nZXRfZGVmYXVsdF9vcGVuc3NsX21ldGhvZCgpKTsKCUVOR0lORV9zZXRfREgoc21hcnRfZW5naW5lLCBESF9nZXRfZGVmYXVsdF9vcGVuc3NsX21ldGhvZCgpKTsKCUVOR0lORV9zZXRfUkFORChzbWFydF9lbmdpbmUsIFJBTkRfU1NMZWF5KCkpOwoJRU5HSU5FX3NldF9CTl9tb2RfZXhwKHNtYXJ0X2VuZ2luZSwgQk5fbW9kX2V4cCk7CgoJcmV0dXJuIHNtYXJ0X2VuZ2luZTsKfQojZW5kaWYKCnN0YXRpYyB2b2lkCmNvbnZlcnRfcnNhX3RvX3JzYTEoS2V5ICogaW4sIEtleSAqIG91dCkKewoJc3RydWN0IHNjX3ByaXZfZGF0YSAqcHJpdjsKCQoJb3V0LT5yc2EtPmZsYWdzID0gaW4tPnJzYS0+ZmxhZ3M7CglvdXQtPmZsYWdzID0gaW4tPmZsYWdzOwoJUlNBX3NldF9tZXRob2Qob3V0LT5yc2EsIFJTQV9nZXRfbWV0aG9kKGluLT5yc2EpKTsKCUJOX2NvcHkob3V0LT5yc2EtPm4sIGluLT5yc2EtPm4pOwoJQk5fY29weShvdXQtPnJzYS0+ZSwgaW4tPnJzYS0+ZSk7Cglwcml2ID0gUlNBX2dldF9hcHBfZGF0YShpbi0+cnNhKTsKCXByaXYtPnJlZl9jb3VudCsrOwoJUlNBX3NldF9hcHBfZGF0YShvdXQtPnJzYSwgcHJpdik7CglyZXR1cm47Cn0KCnN0YXRpYyBpbnQgCnNjX3JlYWRfcHVia2V5KEtleSAqIGssIGNvbnN0IHN0cnVjdCBzY19wa2NzMTVfb2JqZWN0ICpjZXJ0X29iaikKewoJaW50IHI7CglzY19wa2NzMTVfY2VydF90ICpjZXJ0ID0gTlVMTDsKCXN0cnVjdCBzY19wcml2X2RhdGEgKnByaXYgPSBOVUxMOwoJc2NfcGtjczE1X2NlcnRfaW5mb190ICpjaW5mbyA9IGNlcnRfb2JqLT5kYXRhOwoKCVg1MDkgKng1MDkgPSBOVUxMOwoJRVZQX1BLRVkgKnB1YmtleSA9IE5VTEw7Cgl1OCAqcDsKCWNoYXIgKnRtcDsKCQoJZGVidWcoInNjX3JlYWRfcHVia2V5KCkgd2l0aCBjZXJ0IGlkICUwMlgiLCBjaW5mby0+aWQudmFsdWVbMF0pOwoJciA9IHNjX3BrY3MxNV9yZWFkX2NlcnRpZmljYXRlKHAxNWNhcmQsIGNpbmZvLCAmY2VydCk7CglpZiAocikgewoJCWxvZ2l0KCJDZXJ0aWZpY2F0ZSByZWFkIGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9Cgl4NTA5ID0gWDUwOV9uZXcoKTsKCWlmICh4NTA5ID09IE5VTEwpIHsKCQlyID0gLTE7IAoJCWdvdG8gZXJyOwoJfQoJcCA9IGNlcnQtPmRhdGE7CglpZiAoIWQyaV9YNTA5KCZ4NTA5LCAmcCwgY2VydC0+ZGF0YV9sZW4pKSB7CgkJbG9naXQoIlVuYWJsZSB0byBwYXJzZSBYLjUwOSBjZXJ0aWZpY2F0ZSIpOwoJCXIgPSAtMTsKCQlnb3RvIGVycjsKCX0KCXNjX3BrY3MxNV9mcmVlX2NlcnRpZmljYXRlKGNlcnQpOwoJY2VydCA9IE5VTEw7CglwdWJrZXkgPSBYNTA5X2dldF9wdWJrZXkoeDUwOSk7CglYNTA5X2ZyZWUoeDUwOSk7Cgl4NTA5ID0gTlVMTDsKCWlmIChwdWJrZXktPnR5cGUgIT0gRVZQX1BLRVlfUlNBKSB7CgkJbG9naXQoIlB1YmxpYyBrZXkgaXMgb2YgdW5rbm93biB0eXBlIik7CgkJciA9IC0xOwoJCWdvdG8gZXJyOwoJfQoJay0+cnNhID0gRVZQX1BLRVlfZ2V0MV9SU0EocHVia2V5KTsKCUVWUF9QS0VZX2ZyZWUocHVia2V5KTsKCglrLT5yc2EtPmZsYWdzIHw9IFJTQV9GTEFHX1NJR05fVkVSOwoJUlNBX3NldF9tZXRob2Qoay0+cnNhLCBzY19nZXRfcnNhX21ldGhvZCgpKTsKCXByaXYgPSB4bWFsbG9jKHNpemVvZihzdHJ1Y3Qgc2NfcHJpdl9kYXRhKSk7Cglwcml2LT5jZXJ0X2lkID0gY2luZm8tPmlkOwoJcHJpdi0+cmVmX2NvdW50ID0gMTsKCVJTQV9zZXRfYXBwX2RhdGEoay0+cnNhLCBwcml2KTsKCglrLT5mbGFncyA9IEtFWV9GTEFHX0VYVDsKCXRtcCA9IGtleV9maW5nZXJwcmludChrLCBTU0hfRlBfTUQ1LCBTU0hfRlBfSEVYKTsKCWRlYnVnKCJmaW5nZXJwcmludCAlZCAlcyIsIGtleV9zaXplKGspLCB0bXApOwoJeGZyZWUodG1wKTsKCQoJcmV0dXJuIDA7CmVycjoKCWlmIChjZXJ0KQoJCXNjX3BrY3MxNV9mcmVlX2NlcnRpZmljYXRlKGNlcnQpOwoJaWYgKHB1YmtleSkKCQlFVlBfUEtFWV9mcmVlKHB1YmtleSk7CglpZiAoeDUwOSkKCQlYNTA5X2ZyZWUoeDUwOSk7CglyZXR1cm4gcjsKfQoKS2V5ICoqCnNjX2dldF9rZXlzKGNvbnN0IGNoYXIgKmlkLCBjb25zdCBjaGFyICpwaW4pCnsKCUtleSAqaywgKiprZXlzOwoJaW50IGksIHIsIHJlYWxfY291bnQgPSAwLCBrZXlfY291bnQ7CglzY19wa2NzMTVfaWRfdCBjZXJ0X2lkOwoJc2NfcGtjczE1X29iamVjdF90ICpjZXJ0c1szMl07CgljaGFyICpidWYgPSB4c3RyZHVwKGlkKSwgKnA7CgoJZGVidWcoInNjX2dldF9rZXlzIGNhbGxlZDogaWQgPSAlcyIsIGlkKTsKCglpZiAoc2NfcGluICE9IE5VTEwpCgkJeGZyZWUoc2NfcGluKTsKCXNjX3BpbiA9IChwaW4gPT0gTlVMTCkgPyBOVUxMIDogeHN0cmR1cChwaW4pOwoKCWNlcnRfaWQubGVuID0gMDsKCWlmICgocCA9IHN0cmNocihidWYsICc6JykpICE9IE5VTEwpIHsKCQkqcCA9IDA7CgkJcCsrOwoJCXNjX3BrY3MxNV9oZXhfc3RyaW5nX3RvX2lkKHAsICZjZXJ0X2lkKTsKCX0KCXIgPSBzc2NhbmYoYnVmLCAiJWQiLCAmc2NfcmVhZGVyX2lkKTsKCXhmcmVlKGJ1Zik7CglpZiAociAhPSAxKQoJCWdvdG8gZXJyOwoJaWYgKHAxNWNhcmQgPT0gTlVMTCkgewoJCXNjX2Nsb3NlKCk7CgkJciA9IHNjX2luaXQoKTsKCQlpZiAocikgewoJCQllcnJvcigiU21hcnRjYXJkIGluaXQgZmFpbGVkOiAlcyIsIHNjX3N0cmVycm9yKHIpKTsKCQkJZ290byBlcnI7CgkJfQoJfQoJaWYgKGNlcnRfaWQubGVuKSB7CgkJciA9IHNjX3BrY3MxNV9maW5kX2NlcnRfYnlfaWQocDE1Y2FyZCwgJmNlcnRfaWQsICZjZXJ0c1swXSk7CgkJaWYgKHIgPCAwKQoJCQlnb3RvIGVycjsKCQlrZXlfY291bnQgPSAxOwoJfSBlbHNlIHsKCQlyID0gc2NfcGtjczE1X2dldF9vYmplY3RzKHAxNWNhcmQsIFNDX1BLQ1MxNV9UWVBFX0NFUlRfWDUwOSwKCQkJCQkgIGNlcnRzLCAzMik7CgkJaWYgKHIgPT0gMCkgewoJCQlsb2dpdCgiTm8gY2VydGlmaWNhdGVzIGZvdW5kIG9uIHNtYXJ0Y2FyZCIpOwoJCQlyID0gLTE7CgkJCWdvdG8gZXJyOwoJCX0gZWxzZSBpZiAociA8IDApIHsKCQkJZXJyb3IoIkNlcnRpZmljYXRlIGVudW1lcmF0aW9uIGZhaWxlZDogJXMiLAoJCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCQlrZXlfY291bnQgPSByOwoJfQoJLyogRklYTUU6IG9ubHkga2VlcCBlbnRyaWVzIHdpdGggYSBjb3JyZXNwb25kaW5nIHByaXZhdGUga2V5ICovCglrZXlzID0geG1hbGxvYyhzaXplb2YoS2V5ICopICogKGtleV9jb3VudCoyKzEpKTsKCWZvciAoaSA9IDA7IGkgPCBrZXlfY291bnQ7IGkrKykgewoJCWsgPSBrZXlfbmV3KEtFWV9SU0EpOwoJCWlmIChrID09IE5VTEwpCgkJCWJyZWFrOwoJCXIgPSBzY19yZWFkX3B1YmtleShrLCBjZXJ0c1tpXSk7CgkJaWYgKHIpIHsKCQkJZXJyb3IoInNjX3JlYWRfcHVia2V5IGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJCWtleV9mcmVlKGspOwoJCQljb250aW51ZTsKCQl9CgkJa2V5c1tyZWFsX2NvdW50XSA9IGs7CgkJcmVhbF9jb3VudCsrOwoJCWsgPSBrZXlfbmV3KEtFWV9SU0ExKTsKCQlpZiAoayA9PSBOVUxMKQoJCQlicmVhazsKCQljb252ZXJ0X3JzYV90b19yc2ExKGtleXNbcmVhbF9jb3VudC0xXSwgayk7CgkJa2V5c1tyZWFsX2NvdW50XSA9IGs7CgkJcmVhbF9jb3VudCsrOwoJfQoJa2V5c1tyZWFsX2NvdW50XSA9IE5VTEw7CgoJcmV0dXJuIGtleXM7CmVycjoKCXNjX2Nsb3NlKCk7CglyZXR1cm4gTlVMTDsKfQoKaW50CnNjX3B1dF9rZXkoS2V5ICpwcnYsIGNvbnN0IGNoYXIgKmlkKQp7CgllcnJvcigia2V5IHVwbG9hZGluZyBub3QgeWV0IHN1cHBvcnRlZCIpOwoJcmV0dXJuIC0xOwp9CgojZW5kaWYgLyogU01BUlRDQVJEICovCg==