LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9saWJyYXJ5LmgiCiNpbmNsdWRlICJ3aW5lL3NlcnZlci5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJmaWxlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocmVnKTsKCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgIi93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICAidXNlcmRlZi5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSAic3lzdGVtLnJlZyIKCnN0YXRpYyBjb25zdCBXQ0hBUiBDbGFzc2VzUm9vdFdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywwfTsKCiNkZWZpbmUgSVNfT1BUSU9OX0ZBTFNFKGNoKSBcCiAgICAoKGNoKSA9PSAnbicgfHwgKGNoKSA9PSAnTicgfHwgKGNoKSA9PSAnZicgfHwgKGNoKSA9PSAnRicgfHwgKGNoKSA9PSAnMCcpCgovKiBfeG1hbGxvYyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkICpfeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CgogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovKiBfeHN0cmR1cCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfeHN0cmR1cChMUENTVFIgc3RyKQp7CiAgICBMUFNUUiByZXQ7CiAgICBzaXplX3QgbGVuID0gc3RybGVuKHN0cikgKyAxOwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IF94bWFsbG9jKCBsZW4gKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQV1NUUiBfc3RyZHVwbkF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbkEpCnsKICAgIExQV1NUUiByZXQ7CiAgICBzaXplX3QgbGVuVzsKCiAgICBpZiAoIXN0ckEpIHJldHVybiBOVUxMOwogICAgbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLDAsc3RyQSxsZW5BLE5VTEwsMCk7CiAgICByZXQgPSBfeG1hbGxvYyhsZW5XKnNpemVvZihXQ0hBUikrc2l6ZW9mKFdDSEFSKSk7CiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwwLHN0ckEsbGVuQSxyZXQsbGVuVyk7CiAgICByZXRbbGVuV10gPSAwOwogICAgcmV0dXJuIHJldDsKfQoKLyogZHVtcCBhIFVuaWNvZGUgc3RyaW5nIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci91bmljb2RlLmMgKi8Kc3RhdGljIGludCBfZHVtcF9zdHJXKGNvbnN0IFdDSEFSICpzdHIsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBzdGF0aWMgY29uc3QgY2hhciBlc2NhcGVzWzMyXSA9ICIuLi4uLi4uYWJ0bnZmci4uLi4uLi4uLi4uLi5lLi4uLiI7CiAgICBjaGFyIGJ1ZmZlclsyNTZdOwogICAgTFBTVFIgcG9zID0gYnVmZmVyOwogICAgaW50IGNvdW50ID0gMDsKCiAgICBmb3IgKDsgbGVuOyBzdHIrKywgbGVuLS0pCiAgICB7CiAgICAgICAgaWYgKHBvcyA+IGJ1ZmZlciArIHNpemVvZihidWZmZXIpIC0gOCkKICAgICAgICB7CiAgICAgICAgICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgICAgICAgICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgICAgICAgICBwb3MgPSBidWZmZXI7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID4gMTI3KSAgLyogaGV4IGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGxlbiA+IDEgJiYgc3RyWzFdIDwgMTI4ICYmIGlzeGRpZ2l0KChjaGFyKXN0clsxXSkpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFx4JTA0eCIsICpzdHIgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCV4IiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPCAzMikgIC8qIG9jdGFsIG9yIEMgZXNjYXBlICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoISpzdHIgJiYgbGVuID09IDEpIGNvbnRpbnVlOyAgLyogZG8gbm90IG91dHB1dCB0ZXJtaW5hdGluZyBOVUxMICovCiAgICAgICAgICAgIGlmIChlc2NhcGVzWypzdHJdICE9ICcuJykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVjIiwgZXNjYXBlc1sqc3RyXSApOwogICAgICAgICAgICBlbHNlIGlmIChsZW4gPiAxICYmIHN0clsxXSA+PSAnMCcgJiYgc3RyWzFdIDw9ICc3JykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCUwM28iLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVvIiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPT0gJ1xcJyB8fCAqc3RyID09IGVzY2FwZVswXSB8fCAqc3RyID09IGVzY2FwZVsxXSkgKnBvcysrID0gJ1xcJzsKICAgICAgICAqcG9zKysgPSAqc3RyOwogICAgfQogICAgZndyaXRlKCBidWZmZXIsIHBvcyAtIGJ1ZmZlciwgMSwgZiApOwogICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgcmV0dXJuIGNvdW50Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgYW5kIGR1bXAgd2l0aCBwcm9wZXIgZXNjYXBpbmcgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9kdW1wX3N0ckF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBXQ0hBUiAqc3RyVzsKICAgIGludCByZXQ7CgogICAgaWYgKHN0ckEgPT0gTlVMTCkgcmV0dXJuIDA7CiAgICBzdHJXID0gX3N0cmR1cG5BdG9XKHN0ckEsbGVuKTsKICAgIHJldCA9IF9kdW1wX3N0clcoc3RyVyxsZW4sZixlc2NhcGUpOwogICAgZnJlZShzdHJXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGEga2V5IHZhbHVlICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvcmVnaXN0cnkuYyAqLwpzdHJ1Y3Qga2V5X3ZhbHVlIHsKICAgIFdDSEFSICAgICAgICAgICAgKm5hbWVXOyAgIC8qIHZhbHVlIG5hbWUgKi8KICAgIGludCAgICAgICAgICAgICAgIHR5cGU7ICAgIC8qIHZhbHVlIHR5cGUgKi8KICAgIHNpemVfdCAgICAgICAgICAgIGxlbjsgICAgIC8qIHZhbHVlIGRhdGEgbGVuZ3RoIGluIGJ5dGVzICovCiAgICB2b2lkICAgICAgICAgICAgICpkYXRhOyAgICAvKiBwb2ludGVyIHRvIHZhbHVlIGRhdGEgKi8KfTsKCi8qIGR1bXAgYSB2YWx1ZSB0byBhIHRleHQgZmlsZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RhdGljIHZvaWQgX2R1bXBfdmFsdWUoc3RydWN0IGtleV92YWx1ZSAqdmFsdWUsRklMRSAqZikKewogICAgaW50IGksIGNvdW50OwoKICAgIGlmICh2YWx1ZS0+bmFtZVdbMF0pIHsKICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgIGNvdW50ID0gMSArIF9kdW1wX3N0clcodmFsdWUtPm5hbWVXLHN0cmxlblcodmFsdWUtPm5hbWVXKSxmLCJcIlwiIik7CiAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIlwiPSIgKTsKICAgIH0KICAgIGVsc2UgY291bnQgPSBmcHJpbnRmKCBmLCAiQD0iICk7CgogICAgc3dpdGNoKHZhbHVlLT50eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgY2FzZSBSRUdfRVhQQU5EX1NaOgogICAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgIT0gUkVHX1NaKSBmcHJpbnRmKCBmLCAic3RyKCVkKToiLCB2YWx1ZS0+dHlwZSApOwogICAgICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgICAgICBpZiAodmFsdWUtPmRhdGEpIF9kdW1wX3N0clcodmFsdWUtPmRhdGEsdmFsdWUtPmxlbi9zaXplb2YoV0NIQVIpLGYsIlwiXCIiKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+bGVuID09IHNpemVvZihEV09SRCkpIHsKICAgICAgICAgICAgICAgIERXT1JEIGR3OwogICAgICAgICAgICAgICAgbWVtY3B5KCAmZHcsIHZhbHVlLT5kYXRhLCBzaXplb2YoRFdPUkQpICk7CiAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiZHdvcmQ6JTA4bHgiLCBkdyApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogZWxzZSBmYWxsIHRocm91Z2ggKi8KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgPT0gUkVHX0JJTkFSWSkgY291bnQgKz0gZnByaW50ZiggZiwgImhleDoiICk7CiAgICAgICAgICAgIGVsc2UgY291bnQgKz0gZnByaW50ZiggZiwgImhleCgleCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLT5sZW47IGkrKykgewogICAgICAgICAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIiUwMngiLCAqKCh1bnNpZ25lZCBjaGFyICopdmFsdWUtPmRhdGEgKyBpKSApOwogICAgICAgICAgICAgICAgaWYgKGkgPCB2YWx1ZS0+bGVuLTEpIHsKICAgICAgICAgICAgICAgICAgICBmcHV0YyggJywnLCBmICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCsrY291bnQgPiA3NikgewogICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiXFxcbiAgIiApOwogICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZnB1dGMoICdcbicsIGYgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CiAgICBjaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KICAgIHVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKICAgIHVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewogICAgdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfdzMxX2R1bXB0cmVlKHVuc2lnbmVkIHNob3J0IGlkeCx1bnNpZ25lZCBjaGFyICp0eHQsc3RydWN0IF93MzFfdGFiZW50ICp0YWIsc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLEhLRVkgaGtleSx0aW1lX3QgbGFzdG1vZGlmaWVkLCBpbnQgbGV2ZWwpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjbGFzc2VzV1tdID0geycuJywnYycsJ2wnLCdhJywncycsJ3MnLCdlJywncycsMH07CiAgICBzdHJ1Y3QgX3czMV9kaXJlbnQgKmRpcjsKICAgIHN0cnVjdCBfdzMxX2tleWVudCAqa2V5OwogICAgc3RydWN0IF93MzFfdmFsZW50ICp2YWw7CiAgICBIS0VZIHN1YmtleSA9IDA7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVcsIHZhbHVlVzsKICAgIHN0YXRpYyBXQ0hBUiB0YWlsWzQwMF07CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5OwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCBOVUxMICk7CgogICAgd2hpbGUgKGlkeCE9MCkgewogICAgICAgIGRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgogICAgICAgIGlmIChkaXItPmtleV9pZHgpIHsKICAgICAgICAgICAgRFdPUkQgbGVuOwogICAgICAgICAgICBrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgogICAgICAgICAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCB0YWlsLCBzaXplb2YodGFpbCktc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR4dFtrZXktPnN0cmluZ19vZmZdLCBrZXktPmxlbmd0aCk7CiAgICAgICAgICAgIHRhaWxbbGVuL3NpemVvZihXQ0hBUildID0gMDsKCiAgICAgICAgICAgIC8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUKICAgICAgICAgICAgICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhc3RyY21wVyh0YWlsLGNsYXNzZXNXKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3Via2V5KSBOdENsb3NlKCBzdWJrZXkgKTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdGFpbCApOwogICAgICAgICAgICBpZiAoTnRDcmVhdGVLZXkoICZzdWJrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBzdWJrZXkgPSAwOwoKICAgICAgICAgICAgLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCiAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKICAgICAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCkgewogICAgICAgICAgICAgICAgICAgIERXT1JEIGxlbjsKICAgICAgICAgICAgICAgICAgICB2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CiAgICAgICAgICAgICAgICAgICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggdGFpbCwgc2l6ZW9mKHRhaWwpIC0gc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHh0W3ZhbC0+c3RyaW5nX29mZl0sIHZhbC0+bGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICB0YWlsW2xlbi9zaXplb2YoV0NIQVIpXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggc3Via2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIHRhaWwsIGxlbiArIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgfQogICAgaWYgKHN1YmtleSkgTnRDbG9zZSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkKewogICAgSEFORExFIGhmOwogICAgSEtFWSByb290OwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CiAgICBzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKICAgIHVuc2lnbmVkIGNoYXIJCSp0eHQ7CiAgICB1bnNpZ25lZCBpbnQJCWxlbjsKICAgIE9GU1RSVUNUCQlvZnM7CiAgICBCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87CiAgICB0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CiAgICBEV09SRCAgICAgICByOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGhmID0gKEhBTkRMRSlPcGVuRmlsZSgicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKICAgIGlmIChoZj09KEhBTkRMRSlIRklMRV9FUlJPUikgcmV0dXJuOwoKICAgIC8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwogICAgaWYgKCFSZWFkRmlsZShoZiwmaGVhZCxzaXplb2YoaGVhZCksJnIsTlVMTCkgfHwgciE9c2l6ZW9mKGhlYWQpKSB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwogICAgICAgIENsb3NlSGFuZGxlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewogICAgICAgIEVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwogICAgICAgIENsb3NlSGFuZGxlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKICAgIC8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KICAgIHRhYiA9IF94bWFsbG9jKGxlbik7CiAgICBpZiAoIVJlYWRGaWxlKGhmLHRhYixsZW4sJnIsTlVMTCkgfHwgciE9bGVuKSB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOwogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBDbG9zZUhhbmRsZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIHJlYWQgdGV4dCAqLwogICAgdHh0ID0gX3htYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CiAgICBpZiAoLTE9PVNldEZpbGVQb2ludGVyKGhmLGhlYWQudGV4dG9mZixOVUxMLFNFRUtfU0VUKSkgewogICAgICAgIEVSUigiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIENsb3NlSGFuZGxlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIVJlYWRGaWxlKGhmLHR4dCxoZWFkLnRleHRzaXplLCZyLE5VTEwpIHx8IHIhPWhlYWQudGV4dHNpemUpIHsKICAgICAgICBFUlIoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOwogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgQ2xvc2VIYW5kbGUoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CiAgICAgICAgRVJSKCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7CiAgICAgICAgZnJlZSh0YWIpOwogICAgICAgIGZyZWUodHh0KTsKICAgICAgICBDbG9zZUhhbmRsZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbGFzc2VzUm9vdFcgKTsKCiAgICBpZiAoIU50Q3JlYXRlS2V5KCAmcm9vdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxyb290LGxhc3Rtb2RpZmllZCwwKTsKICAgICAgICBOdENsb3NlKCByb290ICk7CiAgICB9CiAgICBmcmVlKHRhYik7CiAgICBmcmVlKHR4dCk7CiAgICBDbG9zZUhhbmRsZShoZik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogIkNSRUciID0gVzk1X1JFR19DUkVHX0lEICovCiAgICBEV09SRAl2ZXJzaW9uOwkvKiA/Pz8/IDB4MDAwMTAwMDAgKi8KICAgIERXT1JECXJnZGJfb2ZmOwkvKiAweDA4IE9mZnNldCBvZiAxc3QgUkdEQi1ibG9jayAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwYyAqLwogICAgV09SRAlyZ2RiX251bTsJLyogMHgxMCAjIG9mIFJHREItYmxvY2tzICovCiAgICBXT1JECXVrMzsKICAgIERXT1JECXVrWzNdOwogICAgLyogcmdrbiAqLwp9IF93OTVjcmVnOwoKLyogU0VDVElPTiAyOiBEaXJlY3RvcnkgaW5mb3JtYXRpb24gKHRyZWUgc3RydWN0dXJlKQogKgogKiBvbmNlIG9uIG9mZnNldCAweDIwCiAqCiAqIHN0cnVjdHVyZTogW3Jna25dW2RrZV0qCShyZXBlYXQgdGlsbCBsYXN0X2RrZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KICAgIERXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KICAgIERXT1JEICAgbGFzdF9ka2U7ICAgICAgIC8qIE9mZnNldCB0byBsYXN0IERLRSA/ICovCiAgICBEV09SRAl1a1s0XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBTVFIga2V5X25hbWUsX3c5NWNyZWcgKmNyZWcsX3c5NXJna24gKnJna24sX3c5NWRrZSAqZGtlLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICBfdzk1ZGtoICogZGtoOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICAvKiBzcGVjaWFsIHJvb3Qga2V5ICovCiAgICBpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KICAgIHsKICAgICAgICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSAqLwogICAgICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgcmV0dXJuIF93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsKTsKICAgICAgICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNlYXJjaCBzdWJibG9jayAqLwogICAgaWYgKCEoZGtoID0gX3c5NV9sb29rdXBfZGtoKGNyZWcsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkpIHsKICAgICAgICBFUlIoImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgc2l6ZV90IGxlbiA9IHN0cmxlbihrZXlfbmFtZSk7CiAgICAgICAgbmV3X2tleV9uYW1lID0gX3htYWxsb2MobGVuK2RraC0+a2V5bmFtZWxlbisyKTsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSwga2V5X25hbWUsIGxlbiApOwogICAgICAgIGlmIChsZW4pIG5ld19rZXlfbmFtZVtsZW4rK10gPSAnXFwnOwogICAgICAgIG1lbWNweSggbmV3X2tleV9uYW1lICsgbGVuLCBka2gtPm5hbWUsIGRraC0+a2V5bmFtZWxlbiApOwogICAgICAgIG5ld19rZXlfbmFtZVtsZW4gKyBka2gtPmtleW5hbWVsZW5dID0gMDsKCiAgICAgICAgLyogd2FsayBzaWJsaW5nIGtleXMgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYgKSB7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShrZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHQpLGYsbGV2ZWwpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjoKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChka2gtPnZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2Rrdihka2gsIGRrZS0+bnJMUywgZGtlLT5uck1TLGYpKSB7CiAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoKGRrZS0+bmV4dHN1YiA9PSAweGZmZmZmZmZmKSAmJiAoZGtoLT52YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF94c3RyZHVwKGtleV9uYW1lKTsKCiAgICAvKiBuZXh0IHN1YiBrZXkgKi8KICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgewogICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShuZXdfa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsLTEpKSB7CiAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9Ci8qIGVuZCB3aW5kb3dzIDk1IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd3MgTlQgcmVnaXN0cnkgbG9hZGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIE5UIFJFR0lTVFJZIExPQURFUiAqLwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2lmbmRlZiBNQVBfRkFJTEVECiNkZWZpbmUgTUFQX0ZBSUxFRCAoKExQVk9JRCktMSkKI2VuZGlmCgojZGVmaW5lIE5UX1JFR19CTE9DS19TSVpFICAgICAgICAgICAgMHgxMDAwCgojZGVmaW5lIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQgICAgICAgMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgTlRfUkVHX1BPT0xfQkxPQ0tfSUQgICAgICAgICAweDZFNjk2MjY4CS8qIGhiaW4gKi8KI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX0lEICAgICAgICAgIDB4NmI2ZSAvKiBuayAqLwojZGVmaW5lIE5UX1JFR19WQUxVRV9CTE9DS19JRCAgICAgICAgMHg2Yjc2IC8qIHZrICovCgovKiBzdWJibG9ja3Mgb2YgbmsgKi8KI2RlZmluZSBOVF9SRUdfSEFTSF9CTE9DS19JRCAgICAgICAgIDB4NjY2YyAvKiBsZiAqLwojZGVmaW5lIE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQgICAgICAgMHg2OTZjIC8qIGxpICovCiNkZWZpbmUgTlRfUkVHX1JJX0JMT0NLX0lECSAgICAgMHg2OTcyIC8qIHJpICovCgojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfVFlQRSAgICAgICAgMHgyMAojZGVmaW5lIE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFICAgMHgyYwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDY2Njc2NTcyICdyZWdmJyovCiAgICBEV09SRAl1azE7CQkvKiAweDA0ICovCiAgICBEV09SRAl1azI7CQkvKiAweDA4ICovCiAgICBGSUxFVElNRQlEYXRlTW9kaWZpZWQ7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXVrNTsJCS8qIDB4MWMgKi8KICAgIERXT1JECXVrNjsJCS8qIDB4MjAgKi8KICAgIERXT1JECVJvb3RLZXlCbG9jazsJLyogMHgyNCAqLwogICAgRFdPUkQJQmxvY2tTaXplOwkvKiAweDI4ICovCiAgICBEV09SRCAgIHVrN1sxMTZdOwogICAgRFdPUkQJQ2hlY2tzdW07IC8qIGF0IG9mZnNldCAweDFGQyAqLwp9IG50X3JlZ2Y7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlibG9ja3NpemU7CiAgICBCWVRFCWRhdGFbMV07Cn0gbnRfaGJpbl9zdWI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NkU2OTYyNjggJ2hiaW4nICovCiAgICBEV09SRAlvZmZfcHJldjsKICAgIERXT1JECW9mZl9uZXh0OwogICAgRFdPUkQJdWsxOwogICAgRFdPUkQJdWsyOwkJLyogMHgxMCAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIDB4MUMgKi8KICAgIG50X2hiaW5fc3ViCWhiaW5fc3ViOwkvKiAweDIwICovCn0gbnRfaGJpbjsKCi8qCiAqIHRoZSB2YWx1ZV9saXN0IGNvbnNpc3RzIG9mIG9mZnNldHMgdG8gdGhlIHZhbHVlcyAodmspCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECVN1YkJsb2NrSWQ7CQkvKiAweDAwIDB4NkI2RSAqLwogICAgV09SRAlUeXBlOwkJCS8qIDB4MDIgZm9yIHRoZSByb290LWtleTogMHgyQywgb3RoZXJ3aXNlIDB4MjAqLwogICAgRklMRVRJTUUJd3JpdGV0aW1lOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CQkJLyogMHgwQyAqLwogICAgRFdPUkQJcGFyZW50X29mZjsJCS8qIDB4MTAgT2Zmc2V0IG9mIE93bmVyL1BhcmVudCBrZXkgKi8KICAgIERXT1JECW5yX3N1YmtleXM7CQkvKiAweDE0IG51bWJlciBvZiBzdWItS2V5cyAqLwogICAgRFdPUkQJdWs4OwkJCS8qIDB4MTggKi8KICAgIERXT1JECWxmX29mZjsJCQkvKiAweDFDIE9mZnNldCBvZiB0aGUgc3ViLWtleSBsZi1SZWNvcmRzICovCiAgICBEV09SRAl1azI7CQkJLyogMHgyMCAqLwogICAgRFdPUkQJbnJfdmFsdWVzOwkJLyogMHgyNCBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl2YWx1ZWxpc3Rfb2ZmOwkJLyogMHgyOCBPZmZzZXQgb2YgdGhlIFZhbHVlLUxpc3QgKi8KICAgIERXT1JECW9mZl9zazsJCQkvKiAweDJjIE9mZnNldCBvZiB0aGUgc2stUmVjb3JkICovCiAgICBEV09SRAlvZmZfY2xhc3M7CQkvKiAweDMwIE9mZnNldCBvZiB0aGUgQ2xhc3MtTmFtZSAqLwogICAgRFdPUkQJdWszOwkJCS8qIDB4MzQgKi8KICAgIERXT1JECXVrNDsJCQkvKiAweDM4ICovCiAgICBEV09SRAl1azU7CQkJLyogMHgzYyAqLwogICAgRFdPUkQJdWs2OwkJCS8qIDB4NDAgKi8KICAgIERXT1JECXVrNzsJCQkvKiAweDQ0ICovCiAgICBXT1JECW5hbWVfbGVuOwkJLyogMHg0OCBuYW1lLWxlbmd0aCAqLwogICAgV09SRAljbGFzc19sZW47CQkvKiAweDRhIGNsYXNzLW5hbWUgbGVuZ3RoICovCiAgICBjaGFyCW5hbWVbMV07CQkvKiAweDRjIGtleS1uYW1lICovCn0gbnRfbms7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlvZmZfbms7CS8qIDB4MDAgKi8KICAgIERXT1JECW5hbWU7CS8qIDB4MDQgKi8KfSBoYXNoX3JlYzsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4NjY2YyAqLwogICAgV09SRAlucl9rZXlzOwkvKiAweDA2ICovCiAgICBoYXNoX3JlYwloYXNoX3JlY1sxXTsKfSBudF9sZjsKCi8qCiBsaXN0IG9mIHN1YmtleXMgd2l0aG91dCBoYXNoCgogbGkgLS0rLS0+bmsKICAgICAgfAogICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk2YyAqLwogICAgV09SRAlucl9rZXlzOwogICAgRFdPUkQJb2ZmX25rWzFdOwp9IG50X2xpOwoKLyoKIHRoaXMgaXMgYSBpbnRlcm1lZGlhdGUgbm9kZQoKIHJpIC0tKy0tPmxpLS0rLS0+bmsKICAgICAgfCAgICAgICArCiAgICAgIHwgICAgICAgKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPmxpLS0rLS0+bmsKICAgICAgICAgICAgICArCgkgICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk3MiAqLwogICAgV09SRAlucl9saTsJCS8qIDB4MDIgbnVtYmVyIG9mZiBvZmZzZXRzICovCiAgICBEV09SRAlvZmZfbGlbMV07CS8qIDB4MDQgcG9pbnRzIHRvIGxpICovCn0gbnRfcmk7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAndmsnICovCiAgICBXT1JECW5hbV9sZW47CiAgICBEV09SRAlkYXRhX2xlbjsKICAgIERXT1JECWRhdGFfb2ZmOwogICAgRFdPUkQJdHlwZTsKICAgIFdPUkQJZmxhZzsKICAgIFdPUkQJdWsxOwogICAgY2hhcgluYW1lWzFdOwp9IG50X3ZrOwoKLyoKICogZ2V0cyBhIHZhbHVlCiAqCiAqIHZrLT5mbGFnOgogKiAgMCB2YWx1ZSBpcyBhIGRlZmF1bHQgdmFsdWUKICogIDEgdGhlIHZhbHVlIGhhcyBhIG5hbWUKICoKICogdmstPmRhdGFfbGVuCiAqICBsZW4gb2YgdGhlIHdob2xlIGRhdGEgYmxvY2sKICogIC0gcmVnX3N6ICh1bmljb2RlKQogKiAgICBieXRlcyBpbmNsdWRpbmcgdGhlIHRlcm1pbmF0aW5nIFwwID0gMioobnVtYmVyX29mX2NoYXJzKzEpCiAqICAtIHJlZ19kd29yZCwgcmVnX2JpbmFyeToKICogICAgaWYgaGlnaGVzdCBiaXQgb2YgZGF0YV9sZW4gaXMgc2V0IGRhdGFfb2ZmIGNvbnRhaW5zIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludCBfbnRfZHVtcF92ayhMUFNUUiBrZXlfbmFtZSwgY2hhciAqYmFzZSwgbnRfdmsgKnZrLEZJTEUgKmYpCnsKICAgIEJZVEUgKnBkYXRhID0gKEJZVEUgKikoYmFzZSt2ay0+ZGF0YV9vZmYrNCk7IC8qIHN0YXJ0IG9mIGRhdGEgKi8KICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CgogICAgaWYgKHZrLT5pZCAhPSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gYmxvY2sgZm91bmQgKDB4JTA0eCksIHBsZWFzZSByZXBvcnQhXG4iLCB2ay0+aWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyh2ay0+bmFtZSx2ay0+bmFtX2xlbik7CiAgICB2YWx1ZS50eXBlID0gdmstPnR5cGU7CiAgICB2YWx1ZS5sZW4gPSAodmstPmRhdGFfbGVuICYgMHg3ZmZmZmZmZik7CiAgICB2YWx1ZS5kYXRhID0gKHZrLT5kYXRhX2xlbiAmIDB4ODAwMDAwMDApID8gKExQQllURSkmKHZrLT5kYXRhX29mZik6IHBkYXRhOwoKICAgIF9kdW1wX3ZhbHVlKCZ2YWx1ZSxmKTsKICAgIGZyZWUodmFsdWUubmFtZVcpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKiBpdCdzIGNhbGxlZCBmcm9tIF9udF9kdW1wX2xmKCkgKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCk7CgovKgogKiBnZXQgdGhlIHN1YmtleXMKICoKICogdGhpcyBzdHJ1Y3R1cmUgY29udGFpbnMgdGhlIGhhc2ggb2YgYSBrZXluYW1lIGFuZCBwb2ludHMgdG8gYWxsCiAqIHN1YmtleXMKICoKICogZXhjZXB0aW9uOiBpZiB0aGUgaWQgaXMgJ2lsJyB0aGVyZSBhcmUgbm8gaGFzaCB2YWx1ZXMgYW5kIGV2ZXJ5CiAqIGR3b3JkIGlzIGEgb2Zmc2V0CiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX2xmKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKmxmLCBGSUxFICpmLCBpbnQgbGV2ZWwpCnsKICAgIGludCBpOwoKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgewogICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIHsgIC8qIHJpICovCiAgICAgICAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CiAgICAgICAgaW50IGxpX3N1YmtleXMgPSAwOwoKICAgICAgICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKICAgICAgICAgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIG51bWJlciAqLwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfbGYoa2V5X25hbWUsIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfSBlbHNlIGdvdG8gZXJyb3IyOwoKICAgIHJldHVybiBUUlVFOwoKZXJyb3IyOgogICAgaWYgKGxmLT5pZCA9PSAweDY4NmMpCiAgICAgICAgRklYTUUoInVua25vd24gV2luIFhQIG5vZGUgaWQgMHg2ODZjOiBkbyB3ZSBuZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBpdCA/XG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwogICAgcmV0dXJuIFRSVUU7CgplcnJvcjE6CiAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwogICAgcmV0dXJuIEZBTFNFOwoKZXJyb3I6CiAgICBFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBfbnRfZHVtcF9uayBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBTVFIga2V5X25hbWUsY2hhciAqYmFzZSxudF9uayAqbmssRklMRSAqZixpbnQgbGV2ZWwpCnsKICAgIHVuc2lnbmVkIGludCBuOwogICAgRFdPUkQgKnZsOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICBUUkFDRSgiJXNcbiIsIGtleV9uYW1lKTsKCiAgICBpZiAobmstPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIG5rLT5TdWJCbG9ja0lkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChuay0+VHlwZSE9TlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpICYmICgoKG50X25rKikoYmFzZStuay0+cGFyZW50X29mZis0KSktPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkpIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oa2V5X25hbWUpOwogICAgICAgIG5ld19rZXlfbmFtZSA9IF94bWFsbG9jKCBsZW4rbmstPm5hbWVfbGVuKzIgKTsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSwga2V5X25hbWUsIGxlbiApOwogICAgICAgIGlmIChsZW4pIG5ld19rZXlfbmFtZVtsZW4rK10gPSAnXFwnOwogICAgICAgIG1lbWNweSggbmV3X2tleV9uYW1lICsgbGVuLCBuay0+bmFtZSwgbmstPm5hbWVfbGVuICk7CiAgICAgICAgbmV3X2tleV9uYW1lW2xlbiArIG5rLT5uYW1lX2xlbl0gPSAwOwoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6CiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAobmstPm5yX3ZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgICAgIGlmICgobmstPm5yX3N1YmtleXMgPT0gMCkgJiYgKG5rLT5ucl92YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQoKICAgICAgICAvKiBsb29wIHRyb3VnaCB0aGUgdmFsdWUgbGlzdCAqLwogICAgICAgIHZsID0gKERXT1JEICopKGJhc2UrbmstPnZhbHVlbGlzdF9vZmYrNCk7CiAgICAgICAgZm9yIChuPTA7IG48bmstPm5yX3ZhbHVlczsgbisrKSB7CiAgICAgICAgICAgIG50X3ZrICogdmsgPSAobnRfdmsqKShiYXNlK3ZsW25dKzQpOwogICAgICAgICAgICBpZiAoIV9udF9kdW1wX3ZrKG5ld19rZXlfbmFtZSwgYmFzZSwgdmssIGYpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3hzdHJkdXAoa2V5X25hbWUpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgc3Via2V5cyAqLwogICAgaWYgKG5rLT5ucl9zdWJrZXlzKSB7CiAgICAgICAgbnRfbGYgKmxmID0gKG50X2xmKikoYmFzZStuay0+bGZfb2ZmKzQpOwogICAgICAgIGlmICghX250X2R1bXBfbGYobmV3X2tleV9uYW1lLCBiYXNlLCBuay0+bnJfc3Via2V5cywgbGYsIGYsIGxldmVsLTEpKSB7CiAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyogZW5kIG50IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NldF9yZWdpc3RyeV9sZXZlbHMgW0ludGVybmFsXQogKgogKiBzZXQgbGV2ZWwgdG8gMCBmb3IgbG9hZGluZyBzeXN0ZW0gZmlsZXMKICogc2V0IGxldmVsIHRvIDEgZm9yIGxvYWRpbmcgdXNlciBmaWxlcwogKi8Kc3RhdGljIHZvaWQgX3NldF9yZWdpc3RyeV9sZXZlbHMoaW50IGxldmVsLGludCBzYXZpbmcsaW50IHBlcmlvZCkKewogICAgU0VSVkVSX1NUQVJUX1JFUSggc2V0X3JlZ2lzdHJ5X2xldmVscyApCiAgICB7CglyZXEtPmN1cnJlbnQgPSBsZXZlbDsKCXJlcS0+c2F2aW5nICA9IHNhdmluZzsKICAgICAgICByZXEtPnBlcmlvZCAgPSBwZXJpb2Q7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyogX3NhdmVfYXRfZXhpdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9zYXZlX2F0X2V4aXQoSEtFWSBoa2V5LExQQ1NUUiBwYXRoKQp7CiAgICBMUENTVFIgY29uZmRpciA9IHdpbmVfZ2V0X2NvbmZpZ19kaXIoKTsKCiAgICBTRVJWRVJfU1RBUlRfUkVRKCBzYXZlX3JlZ2lzdHJ5X2F0ZXhpdCApCiAgICB7CiAgICAgICAgcmVxLT5oa2V5ID0gaGtleTsKICAgICAgICB3aW5lX3NlcnZlcl9hZGRfZGF0YSggcmVxLCBjb25mZGlyLCBzdHJsZW4oY29uZmRpcikgKTsKICAgICAgICB3aW5lX3NlcnZlcl9hZGRfZGF0YSggcmVxLCBwYXRoLCBzdHJsZW4ocGF0aCkrMSApOwogICAgICAgIHdpbmVfc2VydmVyX2NhbGwoIHJlcSApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuCiAqLwpzdGF0aWMgdm9pZCBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTdGF0RGF0YVdbXSA9IHsnRCcsJ3knLCduJywnRCcsJ2EnLCd0JywnYScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUCcsJ2UnLCdyJywnZicsJ1MnLCd0JywnYScsJ3QnLCdzJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywndCcsJ2EnLCd0JywnRCcsJ2EnLCd0JywnYScsMH07CiAgICBIS0VZIGhrZXk7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTdGF0RGF0YVcgKTsKICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgTnRDbG9zZSggaGtleSApOwp9CgojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgICAgMAojZGVmaW5lIFJFR19XSU45NSAgICAgMQojZGVmaW5lIFJFR19XSU5OVCAgICAgMgoKLyogcmV0dXJuIHRoZSB0eXBlIG9mIG5hdGl2ZSByZWdpc3RyeSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF9yZWdfdHlwZSh2b2lkKQp7CiAgICBXQ0hBUiB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBXQ0hBUiB0bXBbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBpbnQgcmV0ID0gUkVHX1dJTjMxOwogICAgc3RhdGljIGNvbnN0IFdDSEFSIG50X3JlZ19wYXRoV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd2luOXhfcmVnX3BhdGhXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnLicsJ2QnLCdhJywndCcsMH07CgogICAgR2V0V2luZG93c0RpcmVjdG9yeVcod2luZGlyLCBNQVhfUEFUSE5BTUVfTEVOKTsKCiAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbTMyL2NvbmZpZy9zeXN0ZW0gLS0+IHdpbm50ICovCiAgICBzdHJjcHlXKHRtcCwgd2luZGlyKTsKICAgIHN0cmNhdFcodG1wLCBudF9yZWdfcGF0aFcpOwogICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNXKHRtcCkgIT0gKERXT1JEKS0xKQogICAgICByZXQgPSBSRUdfV0lOTlQ7CiAgICBlbHNlCiAgICB7CiAgICAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbS5kYXQgLS0+IHdpbjk1ICovCiAgICAgIHN0cmNweVcodG1wLCB3aW5kaXIpOwogICAgICBzdHJjYXRXKHRtcCwgd2luOXhfcmVnX3BhdGhXKTsKICAgICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNXKHRtcCkgIT0gKERXT1JEKS0xKQogICAgICAgIHJldCA9IFJFR19XSU45NTsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKiBsb2FkIHRoZSByZWdpc3RyeSBmaWxlIGluIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVkgaGtleSxMUENTVFIgZm4pCnsKICAgIEhBTkRMRSBmaWxlOwogICAgaWYgKChmaWxlID0gRklMRV9DcmVhdGVGaWxlKCBmbiwgR0VORVJJQ19SRUFELCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX0FUVFJJQlVURV9OT1JNQUwsIDAsIFRSVUUsIERSSVZFX1VOS05PV04gKSkpCiAgICB7CiAgICAgICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF9yZWdpc3RyeSApCiAgICAgICAgewogICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICByZXEtPmZpbGUgICAgPSBmaWxlOwogICAgICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICAgICAgQ2xvc2VIYW5kbGUoIGZpbGUgKTsKICAgIH0KfQoKLyogZ2VuZXJhdGUgYW5kIHJldHVybiB0aGUgbmFtZSBvZiB0aGUgdG1wIGZpbGUgYW5kIGFzc29jaWF0ZWQgc3RyZWFtIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9nZXRfdG1wX2ZuKEZJTEUgKipmKQp7CiAgICBMUFNUUiByZXQ7CiAgICBpbnQgdG1wX2ZkLGNvdW50OwoKICAgIHJldCA9IF94bWFsbG9jKDUwKTsKICAgIGZvciAoY291bnQgPSAwOzspIHsKICAgICAgICBzcHJpbnRmKHJldCwiL3RtcC9yZWclbHglMDR4LnRtcCIsKGxvbmcpZ2V0cGlkKCksY291bnQrKyk7CiAgICAgICAgaWYgKCh0bXBfZmQgPSBvcGVuKHJldCxPX0NSRUFUIHwgT19FWENMIHwgT19XUk9OTFksMDY2NikpICE9IC0xKSBicmVhazsKICAgICAgICBpZiAoZXJybm8gIT0gRUVYSVNUKSB7CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgZnJlZShyZXQpOwogICAgICAgICAgICAqZiA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKCpmID0gZmRvcGVuKHRtcF9mZCwidyIpKSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIGZkb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgY2xvc2UodG1wX2ZkKTsKICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW45NSBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENXU1RSIGZuLCBpbnQgbGV2ZWwpCnsKICAgIGludCBmZDsKICAgIEZJTEUgKmY7CiAgICBET1NfRlVMTF9OQU1FIGZ1bGxfbmFtZTsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgc3RydWN0IHN0YXQgc3Q7CgogICAgX3c5NWNyZWcgKmNyZWc7CiAgICBfdzk1cmdrbiAqcmdrbjsKICAgIF93OTVka2UgKmRrZSwgKnJvb3RfZGtlOwoKICAgIGlmICghRE9TRlNfR2V0RnVsbE5hbWUoIGZuLCAwLCAmZnVsbF9uYW1lICkpIHJldHVybiBOVUxMOwoKICAgIC8qIG1hcCB0aGUgcmVnaXN0cnkgaW50byB0aGUgbWVtb3J5ICovCiAgICBpZiAoKGZkID0gb3BlbihmdWxsX25hbWUubG9uZ19uYW1lLCBPX1JET05MWSB8IE9fTk9OQkxPQ0spKSA9PSAtMSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoKGZzdGF0KGZkLCAmc3QpID09IC0xKSkgZ290byBlcnJvcjE7CiAgICBpZiAoIXN0LnN0X3NpemUpIGdvdG8gZXJyb3IxOwogICAgaWYgKChiYXNlID0gbW1hcChOVUxMLCBzdC5zdF9zaXplLCBQUk9UX1JFQUQsIE1BUF9QUklWQVRFLCBmZCwgMCkpID09IE1BUF9GQUlMRUQpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gVzk1X1JFR19DUkVHX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLAogICAgICAgICAgICBkZWJ1Z3N0cl93KGZuKSk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBjcmVnID0gYmFzZTsKICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CiAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSB7CiAgICAgICAgRVJSKCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVseFxuIiwgcmdrbi0+aWQpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+cm9vdF9vZmYgIT0gMHgyMCkgewogICAgICAgIEVSUigicmdrbi0+cm9vdF9vZmYgbm90IDB4MjAsIHBsZWFzZSByZXBvcnQgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5sYXN0X2RrZSA+IHJna24tPnNpemUpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBsYXN0X2RrZSA+IHNpemUhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIC8qIHZlcmlmeSBsYXN0IGRrZSAqLwogICAgZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPmxhc3RfZGtlKTsKICAgIGlmIChka2UtPngxICE9IDB4ODAwMDAwMDApCiAgICB7IC8qIHdyb25nIG1hZ2ljICovCiAgICAgIEVSUigibGFzdCBka2UgaW52YWxpZCAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5zaXplID4gY3JlZy0+cmdkYl9vZmYpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZ2tuIHNpemUgPiByZ2RiX29mZiAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIHJvb3RfZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPnJvb3Rfb2ZmKTsKICAgIGlmICggKHJvb3RfZGtlLT5wcmV2bHZsICE9IDB4ZmZmZmZmZmYpIHx8IChyb290X2RrZS0+bmV4dCAhPSAweGZmZmZmZmZmKSApCiAgICB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGludmFsaWQgcm9vdCBka2UgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfdzk1X2R1bXBfZGtlKCIiLGNyZWcscmdrbixyb290X2RrZSxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgaWYocmV0ID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzLlxuIiwgZGVidWdzdHJfdyhmbikpOwogICAgICAgIEVSUigiUGxlYXNlIHJlcG9ydCB0aGlzLlxuIik7CiAgICAgICAgRVJSKCJNYWtlIGEgYmFja3VwIG9mIHRoZSBmaWxlLCBydW4gYSBnb29kIHJlZyBjbGVhbmVyIHByb2dyYW0gYW5kIHRyeSBhZ2FpbiFcbiIpOwogICAgfQoKICAgIG11bm1hcChiYXNlLCBzdC5zdF9zaXplKTsKZXJyb3IxOgogICAgY2xvc2UoZmQpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW5udCBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENXU1RSIGZuLCBpbnQgbGV2ZWwpCnsKICAgIEZJTEUgKmY7CiAgICB2b2lkICpiYXNlOwogICAgTFBTVFIgcmV0ID0gTlVMTDsKICAgIEhBTkRMRSBoRmlsZTsKICAgIEhBTkRMRSBoTWFwcGluZzsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBMQVJHRV9JTlRFR0VSIGxnX2ludDsKICAgIE5UU1RBVFVTIG50czsKICAgIFNJWkVfVCBsZW47CgogICAgbnRfcmVnZiAqcmVnZjsKICAgIG50X2hiaW4gKmhiaW47CiAgICBudF9oYmluX3N1YiAqaGJpbl9zdWI7CiAgICBudF9uayAqbms7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CgogICAgaEZpbGUgPSBDcmVhdGVGaWxlVyggZm4sIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CiAgICBpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CiAgICBhdHRyLkxlbmd0aCAgICAgICAgICAgICAgICAgICA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSAgICAgICAgICAgID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSAgICAgICAgICAgICAgID0gTlVMTDsKICAgIGF0dHIuQXR0cmlidXRlcyAgICAgICAgICAgICAgID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yICAgICAgID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBsZ19pbnQuUXVhZFBhcnQgPSAwOwogICAgbnRzID0gTnRDcmVhdGVTZWN0aW9uKCAmaE1hcHBpbmcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFOREFSRF9SSUdIVFNfUkVRVUlSRUR8U0VDVElPTl9RVUVSWXxTRUNUSU9OX01BUF9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAmYXR0ciwgJmxnX2ludCwgUEFHRV9SRUFET05MWSwgU0VDX0NPTU1JVCwgaEZpbGUgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIGJhc2UgPSBOVUxMOyBsZW4gPSAwOwogICAgbnRzID0gTnRNYXBWaWV3T2ZTZWN0aW9uKCBoTWFwcGluZywgR2V0Q3VycmVudFByb2Nlc3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJhc2UsIDAsIDAsICZsZ19pbnQsICZsZW4sIFZpZXdTaGFyZSwgMCwgCgkJCSAgICAgIFBBR0VfUkVBRE9OTFkpOwogICAgTnRDbG9zZSggaE1hcHBpbmcgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gTlRfUkVHX0hFQURFUl9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbm50IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIiwKICAgICAgICAgICAgZGVidWdzdHJfdyhmbikpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogc3RhcnQgYmxvY2sgKi8KICAgIHJlZ2YgPSBiYXNlOwoKICAgIC8qIGhiaW4gYmxvY2sgKi8KICAgIGhiaW4gPSAobnRfaGJpbiopKChjaGFyKikgYmFzZSArIDB4MTAwMCk7CiAgICBpZiAoaGJpbi0+aWQgIT0gTlRfUkVHX1BPT0xfQkxPQ0tfSUQpIHsKICAgICAgRVJSKCAiaGJpbiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBoYmluX3N1YiBibG9jayAqLwogICAgaGJpbl9zdWIgPSAobnRfaGJpbl9zdWIqKSYoaGJpbi0+aGJpbl9zdWIpOwogICAgaWYgKChoYmluX3N1Yi0+ZGF0YVswXSAhPSAnbicpIHx8IChoYmluX3N1Yi0+ZGF0YVsxXSAhPSAnaycpKSB7CiAgICAgIEVSUiggImhiaW5fc3ViIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIG5rIGJsb2NrICovCiAgICBuayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CiAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpIHsKICAgICAgRVJSKCAic3BlY2lhbCBuayBibG9jayBub3QgZm91bmRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF9udF9kdW1wX25rKCIiLChjaGFyKiliYXNlKzB4MTAwMCxuayxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgTnRVbm1hcFZpZXdPZlNlY3Rpb24oIEdldEN1cnJlbnRQcm9jZXNzKCksIGJhc2UgKTsKZXJyb3IxOgogICAgTnRDbG9zZShoRmlsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IG5hdGl2ZSByZWdpc3RyeSB0byB3aW5lIGZvcm1hdCBhbmQgbG9hZCBpdCB2aWEgc2VydmVyIGNhbGwgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoTFBDV1NUUiBmbiwgSEtFWSBoa2V5LCBpbnQgcmVnX3R5cGUsIGludCBsZXZlbCkKewogICAgTFBTVFIgdG1wID0gTlVMTDsKCiAgICBzd2l0Y2ggKHJlZ190eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfV0lOTlQ6CiAgICAgICAgICAgIC8qIEZJWE1FOiBmb2xsb3dpbmcgZnVuY3Rpb24gZG9lc24ndCByZWFsbHkgY29udmVydCB5ZXQgKi8KICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU45NToKICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgRVJSKCJEb24ndCBrbm93IGhvdyB0byBjb252ZXJ0IG5hdGl2ZSAzLjEgcmVnaXN0cnkgeWV0LlxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5rbm93biByZWdpc3RyeSBmb3JtYXQgcGFyYW1ldGVyICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAodG1wICE9IE5VTEwpIHsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleSx0bXApOwogICAgICAgIFRSQUNFKCJGaWxlICVzIHN1Y2Nlc3NmdWxseSBjb252ZXJ0ZWQgdG8gJXMgYW5kIGxvYWRlZCB0byByZWdpc3RyeS5cbiIsCiAgICAgICAgICAgICAgZGVidWdzdHJfdyhmbiksIHRtcCk7CiAgICAgICAgdW5saW5rKHRtcCk7CiAgICB9CiAgICBlbHNlIFdBUk4oIlVuYWJsZSB0byBjb252ZXJ0ICVzIChkb2Vzbid0IGV4aXN0PylcbiIsIGRlYnVnc3RyX3coZm4pKTsKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgbmF0aXZlIHdpbmRvd3MgcmVnaXN0cnkgZmlsZXMgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfbG9jYWxfbWFjaGluZSwgSEtFWSBoa2V5X2N1cnJlbnRfdXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBpbnQgcmVnX3R5cGU7CiAgICBXQ0hBUiB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBXQ0hBUiBwYXRoW01BWF9QQVRITkFNRV9MRU5dOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgSEtFWSBoa2V5OwoKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBXaW5lV1tdID0geydXJywnaScsJ24nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBQcm9maWxlV1tdID0geydQJywncicsJ28nLCdmJywnaScsJ2wnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBlbXB0eV9zdHJXW10gPSB7IDAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTeXN0ZW1bXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTb2Z0d2FyZVtdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgQ2xvbmVbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywneScsJ3MnLCd0JywnZScsJ20nLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ2wnLCdvJywnbicsJ2UnLDB9OwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgR2V0V2luZG93c0RpcmVjdG9yeVcod2luZGlyLCBNQVhfUEFUSE5BTUVfTEVOKTsKCiAgICByZWdfdHlwZSA9IF9nZXRfcmVnX3R5cGUoKTsKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDogewogICAgICAgICAgICBIS0VZIGhrZXk7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBudHVzZXJfZGF0V1tdID0geydcXCcsJ24nLCd0JywndScsJ3MnLCdlJywncicsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgZGVmYXVsdFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdkJywnZScsJ2YnLCdhJywndScsJ2wnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc29mdHdhcmVXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc2FtV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCdhJywnbScsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzZWN1cml0eVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywnZScsJ2MnLCd1JywncicsJ2knLCd0JywneScsMH07CgogICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIG50dXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggV2luZVcsIFByb2ZpbGVXLCBlbXB0eV9zdHJXLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOICkpIHsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgbnR1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9jdXJyZW50X3VzZXIsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTUVTU0FHRSgiV2hlbiB5b3UgYXJlIHJ1bm5pbmcgd2l0aCBhIG5hdGl2ZSBOVCBkaXJlY3Rvcnkgc3BlY2lmeVxuIik7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCInUHJvZmlsZT08cHJvZmlsZWRpcmVjdG9yeT4nIG9yIGRpc2FibGUgbG9hZGluZyBvZiBXaW5kb3dzXG4iKTsKICAgICAgICAgICAgICAgIE1FU1NBR0UoInJlZ2lzdHJ5IChMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXM9TilcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBkZWZhdWx0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAqIEZJWE1FCiAgICAgICAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAgICAgICAqLwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTeXN0ZW0gKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHN5c3RlbVcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU29mdHdhcmUgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNvZnR3YXJlVyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNhbVcpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc2VjdXJpdHlXKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIC8qIHRoaXMga2V5IGlzIGdlbmVyYXRlZCB3aGVuIHRoZSBudC1jb3JlIGJvb3RlZCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgQ2xvbmUgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtXzFzdFdbXSA9IHsnYycsJzonLCdcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJy4nLCcxJywncycsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtX2RhdFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIGNsYXNzZXNfZGF0V1tdID0geydcXCcsJ2MnLCdsJywnYScsJ3MnLCdzJywnZScsJ3MnLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHVzZXJfZGF0V1tdID0geydcXCcsJ3UnLCdzJywnZScsJ3InLCcuJywnZCcsJ2EnLCd0JywwfTsKCiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShzeXN0ZW1fMXN0Vyxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHN5c3RlbV9kYXRXKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU45NSwwKTsKCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIENsYXNzZXNSb290VyApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgY2xhc3Nlc19kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTjk1LDApOwogICAgICAgICAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKFdpbmVXLCBQcm9maWxlVywgZW1wdHlfc3RyVywgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTikpIHsKCSAgICAgICAgLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwoJICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOOTUsMSk7CgoJICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCgkgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCB1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgLyogRklYTUU6IGhlcmUgd2Ugc2hvdWxkIGNvbnZlcnQgdG8gKi5yZWcgZmlsZSBzdXBwb3J0ZWQgYnkgc2VydmVyIGFuZCBjYWxsIFJFUV9MT0FEX1JFR0lTVFJZLCBzZWUgUkVHX1dJTjk1IGNhc2UgKi8KICAgICAgICAgICAgX3czMV9sb2FkcmVnKCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFJFR19ET05UTE9BRDoKICAgICAgICAgICAgVFJBQ0UoIlJFR19ET05UTE9BRFxuIik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoInN3aXRjaDogbm8gbWF0Y2ggKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgIH0KfQoKLyogbG9hZCBob21lIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gfi8ud2luZSkgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF9ob21lX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfbG9jYWxfbWFjaGluZSwgSEtFWSBoa2V5X2N1cnJlbnRfdXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBMUENTVFIgY29uZmRpciA9IHdpbmVfZ2V0X2NvbmZpZ19kaXIoKTsKICAgIExQU1RSIHRtcCA9IF94bWFsbG9jKHN0cmxlbihjb25mZGlyKSsyMCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleV91c2Vyc19kZWZhdWx0LHRtcCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUik7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleV9jdXJyZW50X3VzZXIsdG1wKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleV9sb2NhbF9tYWNoaW5lLHRtcCk7CgogICAgZnJlZSh0bXApOwp9CgoKLyogbG9hZCBhbGwgcmVnaXN0cnkgKG5hdGl2ZSBhbmQgZ2xvYmFsIGFuZCBob21lKSAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICAgIEhLRVkgaGtleV9sb2NhbF9tYWNoaW5lLCBoa2V5X3VzZXJzLCBoa2V5X3VzZXJzX2RlZmF1bHQsIGhrZXlfY3VycmVudF91c2VyLCBoa2V5X2NvbmZpZzsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIERXT1JEIGNvdW50OwogICAgQk9PTCByZXM7CiAgICBpbnQgYWxsLCBwZXJpb2Q7CiAgICBjaGFyIHRtcFsxMDI0XTsKCiAgICBzdGF0aWMgY29uc3QgV0NIQVIgTWFjaGluZVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgVXNlcldbXSA9IHsnVScsJ3MnLCdlJywncicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgRGVmYXVsdFdbXSA9IHsnLicsJ0QnLCdlJywnZicsJ2EnLCd1JywnbCcsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFJlZ2lzdHJ5V1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbG9hZF93aW5fcmVnX2ZpbGVzV1tdID0geydMJywnbycsJ2EnLCdkJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRicsJ2knLCdsJywnZScsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxvYWRfZ2xvYmFsX3JlZ19maWxlc1dbXSA9IHsnTCcsJ28nLCdhJywnZCcsJ0cnLCdsJywnbycsJ2InLCdhJywnbCcsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRicsJ2knLCdsJywnZScsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxvYWRfaG9tZV9yZWdfZmlsZXNXW10gPSB7J0wnLCdvJywnYScsJ2QnLCdIJywnbycsJ20nLCdlJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU2F2ZU9ubHlVcGRhdGVkS2V5c1dbXSA9IHsnUycsJ2EnLCd2JywnZScsJ08nLCduJywnbCcsJ3knLCdVJywncCcsJ2QnLCdhJywndCcsJ2UnLCdkJywnSycsJ2UnLCd5JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUGVyaW9kaWNTYXZlV1tdID0geydQJywnZScsJ3InLCdpJywnbycsJ2QnLCdpJywnYycsJ1MnLCdhJywndicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFdyaXRldG9Ib21lUmVnaXN0cnlGaWxlc1dbXSA9IHsnVycsJ3InLCdpJywndCcsJ2UnLCd0JywnbycsJ0gnLCdvJywnbScsJ2UnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0YnLCdpJywnbCcsJ2UnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBHbG9iYWxSZWdpc3RyeURpcldbXSA9IHsnRycsJ2wnLCdvJywnYicsJ2EnLCdsJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdEJywnaScsJ3InLDB9OwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGlmICghQ0xJRU5UX0lzQm9vdFRocmVhZCgpKSByZXR1cm47ICAvKiBhbHJlYWR5IGxvYWRlZCAqLwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTWFjaGluZVcgKTsKICAgIE50Q3JlYXRlS2V5KCAmaGtleV9sb2NhbF9tYWNoaW5lLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFVzZXJXICk7CiAgICBOdENyZWF0ZUtleSggJmhrZXlfdXNlcnMsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApOwoKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXlfdXNlcnM7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBEZWZhdWx0VyApOwogICAgaWYgKE50Q3JlYXRlS2V5KCAmaGtleV91c2Vyc19kZWZhdWx0LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgSEtFWV9VU0VSUy8uRGVmYXVsdFxuIiApOwogICAgICAgIEV4aXRQcm9jZXNzKDEpOwogICAgfQogICAgUnRsT3BlbkN1cnJlbnRVc2VyKCBLRVlfQUxMX0FDQ0VTUywgJmhrZXlfY3VycmVudF91c2VyICk7CgogICAgX3NldF9yZWdpc3RyeV9sZXZlbHMoMCwwLDApOwogICAgX2FsbG9jYXRlX2RlZmF1bHRfa2V5cygpOwoKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBSZWdpc3RyeVcgKTsKICAgIGlmIChOdE9wZW5LZXkoICZoa2V5X2NvbmZpZywgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkpIGhrZXlfY29uZmlnID0gMDsKCiAgICAvKiBsb2FkIHdpbmRvd3MgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gaGtleV9jb25maWc7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBsb2FkX3dpbl9yZWdfZmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKSBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBoa2V5X2xvY2FsX21hY2hpbmUsIGhrZXlfY3VycmVudF91c2VyLCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKCiAgICAvKiBsb2FkIGdsb2JhbCByZWdpc3RyeSBpZiByZXF1aXJlZCAqLwoKICAgIHJlcyA9IFRSVUU7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBsb2FkX2dsb2JhbF9yZWdfZmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKQogICAgewogICAgICAgIC8qIGxvYWQgZ2xvYmFsIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gL2V0Yy93aW5lKSAqLwogICAgICAgIGNoYXIgKnAsIGNvbmZpZ2ZpbGVbTUFYX1BBVEhOQU1FX0xFTl07CgogICAgICAgIC8qIE92ZXJyaWRlIEVUQ0RJUj8gKi8KICAgICAgICBjb25maWdmaWxlWzBdID0gMDsKICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBHbG9iYWxSZWdpc3RyeURpclcgKTsKICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3RyLCAtMSwgY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLCBOVUxMLCBOVUxMKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNvbmZpZ2ZpbGVbMF0gIT0gJy8nKSBzdHJjcHkoY29uZmlnZmlsZSwgRVRDRElSKTsKCiAgICAgICAgVFJBQ0UoIkdsb2JhbFJlZ2lzdHJ5RGlyIGlzICclcycuXG4iLCBjb25maWdmaWxlKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgICAgIHAgPSBjb25maWdmaWxlICsgc3RybGVuKGNvbmZpZ2ZpbGUpOwogICAgICAgIHN0cmNweShwLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfdXNlcnMsIGNvbmZpZ2ZpbGUgKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICAgICAgc3RyY3B5KHAsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfbG9jYWxfbWFjaGluZSwgY29uZmlnZmlsZSApOwogICAgfQoKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDEsMCwwKTsKCiAgICAvKiBsb2FkIGhvbWUgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF9ob21lX3JlZ19maWxlc1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIHJlcyA9ICFJU19PUFRJT05fRkFMU0Uoc3RyWzBdKTsKICAgIH0KICAgIGlmIChyZXMpIF9sb2FkX2hvbWVfcmVnaXN0cnkoIGhrZXlfbG9jYWxfbWFjaGluZSwgaGtleV9jdXJyZW50X3VzZXIsIGhrZXlfdXNlcnNfZGVmYXVsdCApOwoKICAgIC8qIHNldHVwIHJlZ2lzdHJ5IHNhdmluZyAqLwoKICAgIGFsbCA9IEZBTFNFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU2F2ZU9ubHlVcGRhdGVkS2V5c1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIGFsbCA9IElTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQoKICAgIHBlcmlvZCA9IDA7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBQZXJpb2RpY1NhdmVXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICBwZXJpb2QgPSAoaW50KXN0cnRvbFcoc3RyLCBOVUxMLCAxMCk7CiAgICB9CgogICAgLyogc2V0IHNhdmluZyBsZXZlbCAoMCBmb3Igc2F2aW5nIGV2ZXJ5dGhpbmcsIDEgZm9yIHNhdmluZyBvbmx5IG1vZGlmaWVkIGtleXMpICovCiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLCFhbGwscGVyaW9kKjEwMDApOwoKICAgIC8qIHNldHVwIGtleXMgdG8gc2F2ZSAqLwoKICAgIHJlcyA9IFRSVUU7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBXcml0ZXRvSG9tZVJlZ2lzdHJ5RmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKQogICAgewogICAgICAgIF9zYXZlX2F0X2V4aXQoaGtleV9jdXJyZW50X3VzZXIsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUiApOwogICAgICAgIF9zYXZlX2F0X2V4aXQoaGtleV9sb2NhbF9tYWNoaW5lLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfdXNlcnNfZGVmYXVsdCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgIH0KCiAgICBOdENsb3NlKGhrZXlfdXNlcnNfZGVmYXVsdCk7CiAgICBOdENsb3NlKGhrZXlfY3VycmVudF91c2VyKTsKICAgIE50Q2xvc2UoaGtleV91c2Vycyk7CiAgICBOdENsb3NlKGhrZXlfbG9jYWxfbWFjaGluZSk7CiAgICBOdENsb3NlKGhrZXlfY29uZmlnKTsKfQo=