LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhd2F5IGxpa2UgYSBtYWRtYW4gYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZm5kZWYgQ1VSTF9ESVNBQkxFX0ZUUAojaWZkZWYgSEFWRV9LUkI0CgojaW5jbHVkZSA8c3RkbGliLmg+CiNpZmRlZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxrcmIuaD4KI2luY2x1ZGUgPGRlcy5oPgoKI2lmZGVmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPiAvKiBmb3IgZ2V0cGlkKCkgKi8KI2VuZGlmCgojaW5jbHVkZSAidXJsZGF0YS5oIgojaW5jbHVkZSAiYmFzZTY0LmgiCiNpbmNsdWRlICJmdHAuaCIKI2luY2x1ZGUgInNlbmRmLmgiCiNpbmNsdWRlICJrcmI0LmgiCiNpbmNsdWRlICJtZW1vcnkuaCIKCiNpZiBkZWZpbmVkKEhBVkVfSU5FVF9OVE9BX1IpICYmICFkZWZpbmVkKEhBVkVfSU5FVF9OVE9BX1JfREVDTCkKI2luY2x1ZGUgImluZXRfbnRvYV9yLmgiCiNlbmRpZgoKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgoKI2RlZmluZSBMT0NBTF9BRERSICgmY29ubi0+bG9jYWxfYWRkcikKI2RlZmluZSBSRU1PVEVfQUREUiBjb25uLT5pcF9hZGRyLT5haV9hZGRyCiNkZWZpbmUgbXljdGxhZGRyIExPQ0FMX0FERFIKI2RlZmluZSBoaXNjdGxhZGRyIFJFTU9URV9BRERSCgpzdHJ1Y3Qga3JiNF9kYXRhIHsKICBkZXNfY2Jsb2NrIGtleTsKICBkZXNfa2V5X3NjaGVkdWxlIHNjaGVkdWxlOwogIGNoYXIgbmFtZVtBTkFNRV9TWl07CiAgY2hhciBpbnN0YW5jZVtJTlNUX1NaXTsKICBjaGFyIHJlYWxtW1JFQUxNX1NaXTsKfTsKCiNpZm5kZWYgSEFWRV9TVFJMQ1BZCi8qIGlmIGl0IGV2ZXIgZ29lcyBub24tc3RhdGljLCBtYWtlIGl0IEN1cmxfIHByZWZpeGVkISAqLwpzdGF0aWMgc2l6ZV90CnN0cmxjcHkgKGNoYXIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3QgZHN0X3N6KQp7CiAgc2l6ZV90IG47CiAgY2hhciAqcDsKCiAgZm9yIChwID0gZHN0LCBuID0gMDsKICAgICAgIG4gKyAxIDwgZHN0X3N6ICYmICpzcmMgIT0gJ1wwJzsKICAgICAgICsrcCwgKytzcmMsICsrbikKICAgICpwID0gKnNyYzsKICAqcCA9ICdcMCc7CiAgaWYgKCpzcmMgPT0gJ1wwJykKICAgIHJldHVybiBuOwogIGVsc2UKICAgIHJldHVybiBuICsgc3RybGVuIChzcmMpOwp9CiNlbHNlCnNpemVfdCBzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2NoZWNrX3Byb3Qodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCkKewogIGFwcF9kYXRhID0gTlVMTDsgLyogcHJldmVudCBjb21waWxlciB3YXJuaW5nICovCiAgaWYobGV2ZWwgPT0gcHJvdF9jb25maWRlbnRpYWwpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAogICAgICAgICAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBNU0dfREFUIG07CiAgaW50IGU7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwoKICBpZihsZXZlbCA9PSBwcm90X3NhZmUpCiAgICBlID0ga3JiX3JkX3NhZmUoYnVmLCBsZW4sICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLCAmbSk7CiAgZWxzZQogICAgZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIsCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICBpZihlKSB7CiAgICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSA9IGNvbm4tPmRhdGE7CiAgICBpbmZvZihkYXRhLCAia3JiNF9kZWNvZGU6ICVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKICAgIHJldHVybiAtMTsKICB9CiAgbWVtbW92ZShidWYsIG0uYXBwX2RhdGEsIG0uYXBwX2xlbmd0aCk7CiAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAvKiBubyBhcmd1bWVudHMgYXJlIHVzZWQsIGp1c3QgaW5pdCB0aGVtIHRvIHByZXZlbnQgY29tcGlsZXIgd2FybmluZ3MgKi8KICBhcHBfZGF0YSA9IE5VTEw7CiAgbGV2ZWwgPSAwOwogIGxlbiA9IDA7CiAgcmV0dXJuIDMxOwp9CgpzdGF0aWMgaW50CmtyYjRfZW5jb2RlKHZvaWQgKmFwcF9kYXRhLCB2b2lkICpmcm9tLCBpbnQgbGVuZ3RoLCBpbnQgbGV2ZWwsIHZvaWQgKip0bywKICAgICAgICAgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogICp0byA9IG1hbGxvYyhsZW5ndGggKyAzMSk7CiAgaWYobGV2ZWwgPT0gcHJvdF9zYWZlKQogICAgcmV0dXJuIGtyYl9ta19zYWZlKGZyb20sICp0bywgbGVuZ3RoLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgZWxzZSBpZihsZXZlbCA9PSBwcm90X3ByaXZhdGUpCiAgICByZXR1cm4ga3JiX21rX3ByaXYoZnJvbSwgKnRvLCBsZW5ndGgsIGQtPnNjaGVkdWxlLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgZWxzZQogICAgcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50Cm1rX2F1dGgoc3RydWN0IGtyYjRfZGF0YSAqZCwgS1RFWFQgYWRhdCwKICAgICAgICBjb25zdCBjaGFyICpzZXJ2aWNlLCBjaGFyICpob3N0LCBpbnQgY2hlY2tzdW0pCnsKICBpbnQgcmV0OwogIENSRURFTlRJQUxTIGNyZWQ7CiAgY2hhciBzbmFtZVtTTkFNRV9TWl0sIGluc3RbSU5TVF9TWl0sIHJlYWxtW1JFQUxNX1NaXTsKCiAgc3RybGNweShzbmFtZSwgc2VydmljZSwgc2l6ZW9mKHNuYW1lKSk7CiAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgcmV0ID0ga3JiX21rX3JlcShhZGF0LCBzbmFtZSwgaW5zdCwgcmVhbG0sIGNoZWNrc3VtKTsKICBpZihyZXQpCiAgICByZXR1cm4gcmV0OwogIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICBzdHJsY3B5KHJlYWxtLCBrcmJfcmVhbG1vZmhvc3QoaG9zdCksIHNpemVvZihyZWFsbSkpOwogIHJldCA9IGtyYl9nZXRfY3JlZChzbmFtZSwgaW5zdCwgcmVhbG0sICZjcmVkKTsKICBtZW1tb3ZlKCZkLT5rZXksICZjcmVkLnNlc3Npb24sIHNpemVvZihkZXNfY2Jsb2NrKSk7CiAgZGVzX2tleV9zY2hlZCgmZC0+a2V5LCBkLT5zY2hlZHVsZSk7CiAgbWVtc2V0KCZjcmVkLCAwLCBzaXplb2YoY3JlZCkpOwogIHJldHVybiByZXQ7Cn0KCiNpZmRlZiBIQVZFX0tSQl9HRVRfT1VSX0lQX0ZPUl9SRUFMTQppbnQga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKGNoYXIgKiwgc3RydWN0IGluX2FkZHIgKik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2F1dGgodm9pZCAqYXBwX2RhdGEsIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgY2hhciAqcDsKICB1bnNpZ25lZCBjaGFyICpwdHI7CiAgc2l6ZV90IGxlbjsKICBLVEVYVF9TVCBhZGF0OwogIE1TR19EQVQgbXNnX2RhdGE7CiAgaW50IGNoZWNrc3VtOwogIHVfaW50MzJfdCBjczsKICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgY2hhciAqaG9zdCA9IGNvbm4tPmhvc3QubmFtZTsKICBzc2l6ZV90IG5yZWFkOwogIGludCBsID0gc2l6ZW9mKGNvbm4tPmxvY2FsX2FkZHIpOwogIHN0cnVjdCBTZXNzaW9uSGFuZGxlICpkYXRhID0gY29ubi0+ZGF0YTsKICBDVVJMY29kZSByZXN1bHQ7CgogIGlmKGdldHNvY2tuYW1lKGNvbm4tPnNvY2tbRklSU1RTT0NLRVRdLAogICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHIgKilMT0NBTF9BRERSLCAmbCkgPCAwKQogICAgcGVycm9yKCJnZXRzb2NrbmFtZSgpIik7CgogIGNoZWNrc3VtID0gZ2V0cGlkKCk7CiAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgImZ0cCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQgPT0gS0RDX1BSX1VOS05PV04pCiAgICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAicmNtZCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQpIHsKICAgIGluZm9mKGRhdGEsICIlc1xuIiwga3JiX2dldF9lcnJfdGV4dChyZXQpKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KCiNpZmRlZiBIQVZFX0tSQl9HRVRfT1VSX0lQX0ZPUl9SRUFMTQogIGlmIChrcmJfZ2V0X2NvbmZpZ19ib29sKCJuYXRfaW5fdXNlIikpIHsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiAqbG9jYWxhZGRyICA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSOwogICAgc3RydWN0IGluX2FkZHIgbmF0QWRkcjsKCiAgICBpZiAoa3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKGtyYl9yZWFsbW9maG9zdChob3N0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5hdEFkZHIpICE9IEtTVUNDRVNTCiAgICAgICAgJiYga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKE5VTEwsICZuYXRBZGRyKSAhPSBLU1VDQ0VTUykKICAgICAgaW5mb2YoZGF0YSwgIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoaG9zdCkpOwogICAgZWxzZSB7CiAgICAgIGlmIChuYXRBZGRyLnNfYWRkciAhPSBsb2NhbGFkZHItPnNpbl9hZGRyLnNfYWRkcikgewojaWZkZWYgSEFWRV9JTkVUX05UT0FfUgogICAgICAgIGNoYXIgbnRvYV9idWZbNjRdOwogICAgICAgIGNoYXIgKmlwID0gKGNoYXIgKilpbmV0X250b2FfcihuYXRBZGRyLCBudG9hX2J1Ziwgc2l6ZW9mKG50b2FfYnVmKSk7CiNlbHNlCiAgICAgICAgY2hhciAqaXAgPSAoY2hhciAqKWluZXRfbnRvYShuYXRBZGRyKTsKI2VuZGlmCiAgICAgICAgaW5mb2YoZGF0YSwgIlVzaW5nIE5BVCBJUCBhZGRyZXNzICglcykgZm9yIGtlcmJlcm9zIDRcbiIsIGlwKTsKICAgICAgICBsb2NhbGFkZHItPnNpbl9hZGRyID0gbmF0QWRkcjsKICAgICAgfQogICAgfQogIH0KI2VuZGlmCgogIGlmKEN1cmxfYmFzZTY0X2VuY29kZSgoY2hhciAqKWFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJnApIDwgMSkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmciKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiQURBVCAlcyIsIHApOwoKICBmcmVlKHApOwoKICBpZihyZXN1bHQpCiAgICByZXR1cm4gLTI7CgogIGlmKEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKSkKICAgIHJldHVybiAtMTsKCiAgaWYoZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICcyJyl7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJTZXJ2ZXIgZGlkbid0IGFjY2VwdCBhdXRoIGRhdGEiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KCiAgcCA9IHN0cnN0cihkYXRhLT5zdGF0ZS5idWZmZXIsICJBREFUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJSZW1vdGUgaG9zdCBkaWRuJ3Qgc2VuZCBhZGF0IHJlcGx5Iik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcCArPSA1OwogIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCAmcHRyKTsKICBpZihsZW4gPiBzaXplb2YoYWRhdC5kYXQpLTEpIHsKICAgIGZyZWUocHRyKTsKICAgIGxlbj0wOwogIH0KICBpZighbGVuIHx8ICFwdHIpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGZyb20gc2VydmVyIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgbWVtY3B5KChjaGFyICopYWRhdC5kYXQsIHB0ciwgbGVuKTsKICBmcmVlKHB0cik7CiAgYWRhdC5sZW5ndGggPSBsZW47CiAgcmV0ID0ga3JiX3JkX3NhZmUoYWRhdC5kYXQsIGFkYXQubGVuZ3RoLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKiloaXNjdGxhZGRyLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilteWN0bGFkZHIsICZtc2dfZGF0YSk7CiAgaWYocmV0KSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJFcnJvciByZWFkaW5nIHJlcGx5IGZyb20gc2VydmVyOiAlcyIsCiAgICAgICAgICAgICAgIGtyYl9nZXRfZXJyX3RleHQocmV0KSk7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAga3JiX2dldF9pbnQobXNnX2RhdGEuYXBwX2RhdGEsICZjcywgNCwgMCk7CiAgaWYoY3MgLSBjaGVja3N1bSAhPSAxKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJCYWQgY2hlY2tzdW0gcmV0dXJuZWQgZnJvbSBzZXJ2ZXIiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICByZXR1cm4gQVVUSF9PSzsKfQoKc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoIEN1cmxfa3JiNF9jbGllbnRfbWVjaCA9IHsKICAgICJLRVJCRVJPU19WNCIsCiAgICBzaXplb2Yoc3RydWN0IGtyYjRfZGF0YSksCiAgICBOVUxMLCAvKiBpbml0ICovCiAgICBrcmI0X2F1dGgsCiAgICBOVUxMLCAvKiBlbmQgKi8KICAgIGtyYjRfY2hlY2tfcHJvdCwKICAgIGtyYjRfb3ZlcmhlYWQsCiAgICBrcmI0X2VuY29kZSwKICAgIGtyYjRfZGVjb2RlCn07CgpDVVJMY29kZSBDdXJsX2tyYl9rYXV0aChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBkZXNfY2Jsb2NrIGtleTsKICBkZXNfa2V5X3NjaGVkdWxlIHNjaGVkdWxlOwogIEtURVhUX1NUIHRrdCwgdGt0Y29weTsKICBjaGFyICpuYW1lOwogIGNoYXIgKnA7CiAgY2hhciBwYXNzd2RbMTAwXTsKICBzaXplX3QgdG1wOwogIHNzaXplX3QgbnJlYWQ7CiAgaW50IHNhdmU7CiAgQ1VSTGNvZGUgcmVzdWx0OwogIHVuc2lnbmVkIGNoYXIgKnB0cjsKCiAgc2F2ZSA9IEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBwcm90X3ByaXZhdGUpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzIiwgY29ubi0+dXNlcik7CgogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIHJlc3VsdCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKXsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCArPSAyOwogIHRtcCA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCAmcHRyKTsKICBpZih0bXAgPj0gc2l6ZW9mKHRrdC5kYXQpKSB7CiAgICBmcmVlKHB0cik7CiAgICB0bXA9MDsKICB9CiAgaWYoIXRtcCB8fCAhcHRyKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBpbiByZXBseS5cbiIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQogIG1lbWNweSgoY2hhciAqKXRrdC5kYXQsIHB0ciwgdG1wKTsKICBmcmVlKHB0cik7CiAgdGt0Lmxlbmd0aCA9IHRtcDsKICB0a3Rjb3B5Lmxlbmd0aCA9IHRrdC5sZW5ndGg7CgogIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiQmFkIHJlcGx5IGZyb20gc2VydmVyIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CiAgbmFtZSA9IHAgKyAyOwogIGZvcig7ICpwICYmICpwICE9ICcgJyAmJiAqcCAhPSAnXHInICYmICpwICE9ICdcbic7IHArKyk7CiAgKnAgPSAwOwoKICBkZXNfc3RyaW5nX3RvX2tleSAoY29ubi0+cGFzc3dkLCAma2V5KTsKICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKCiAgZGVzX3BjYmNfZW5jcnlwdCgodm9pZCAqKXRrdC5kYXQsICh2b2lkICopdGt0Y29weS5kYXQsCiAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICBpZiAoc3RyY21wICgoY2hhciopdGt0Y29weS5kYXQgKyA4LAogICAgICAgICAgICAgIEtSQl9USUNLRVRfR1JBTlRJTkdfVElDS0VUKSAhPSAwKSB7CiAgICBhZnNfc3RyaW5nX3RvX2tleShwYXNzd2QsCiAgICAgICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoY29ubi0+aG9zdC5uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICZrZXkpOwogICAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICB9CiAgbWVtc2V0KGtleSwgMCwgc2l6ZW9mKGtleSkpOwogIG1lbXNldChzY2hlZHVsZSwgMCwgc2l6ZW9mKHNjaGVkdWxlKSk7CiAgbWVtc2V0KHBhc3N3ZCwgMCwgc2l6ZW9mKHBhc3N3ZCkpOwogIGlmKEN1cmxfYmFzZTY0X2VuY29kZSgoY2hhciAqKXRrdGNvcHkuZGF0LCB0a3Rjb3B5Lmxlbmd0aCwgJnApIDwgMSkgewogICAgZmFpbGYoY29ubi0+ZGF0YSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nLiIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX09VVF9PRl9NRU1PUlk7CiAgfQogIG1lbXNldCAodGt0Y29weS5kYXQsIDAsIHRrdGNvcHkubGVuZ3RoKTsKCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiU0lURSBLQVVUSCAlcyAlcyIsIG5hbWUsIHApOwogIGZyZWUocCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKCiAgcmVzdWx0ID0gQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CiAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwoKICByZXR1cm4gQ1VSTEVfT0s7Cn0KCiNlbmRpZiAvKiBIQVZFX0tSQjQgKi8KI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8K