LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxmY250bC5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbm50LmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgoKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAqLwojZGVmaW5lIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FIEVUQ0RJUiIvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUiAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgInVzZXJkZWYucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgInN5c3RlbS5yZWciCgovKiBfeG1hbGxvYyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkICpfeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CgogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovKiBfc3RyZHVwbkEgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX3N0cmR1cG5BKExQQ1NUUiBzdHIsc2l6ZV90IGxlbikKewogICAgTFBTVFIgcmV0OwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IF94bWFsbG9jKCBsZW4gKyAxICk7CiAgICBtZW1jcHkoIHJldCwgc3RyLCBsZW4gKTsKICAgIHJldFtsZW5dID0gMHgwMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgYW5zaSBzdHJpbmcgdG8gdW5pY29kZSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFdTVFIgX3N0cmR1cG5BdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW5BKQp7CiAgICBMUFdTVFIgcmV0OwogICAgc2l6ZV90IGxlblc7CgogICAgaWYgKCFzdHJBKSByZXR1cm4gTlVMTDsKICAgIGxlblcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwwLHN0ckEsbGVuQSxOVUxMLDApOwogICAgcmV0ID0gX3htYWxsb2MobGVuVypzaXplb2YoV0NIQVIpK3NpemVvZihXQ0hBUikpOwogICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsMCxzdHJBLGxlbkEscmV0LGxlblcpOwogICAgcmV0W2xlblddID0gMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGR1bXAgYSBVbmljb2RlIHN0cmluZyB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvdW5pY29kZS5jICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyVyhjb25zdCBXQ0hBUiAqc3RyLHNpemVfdCBsZW4sRklMRSAqZixjaGFyIGVzY2FwZVsyXSkKewogICAgc3RhdGljIGNvbnN0IGNoYXIgZXNjYXBlc1szMl0gPSAiLi4uLi4uLmFidG52ZnIuLi4uLi4uLi4uLi4uZS4uLi4iOwogICAgY2hhciBidWZmZXJbMjU2XTsKICAgIExQU1RSIHBvcyA9IGJ1ZmZlcjsKICAgIGludCBjb3VudCA9IDA7CgogICAgZm9yICg7IGxlbjsgc3RyKyssIGxlbi0tKQogICAgewogICAgICAgIGlmIChwb3MgPiBidWZmZXIgKyBzaXplb2YoYnVmZmVyKSAtIDgpCiAgICAgICAgewogICAgICAgICAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICAgICAgICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgICAgICAgICAgcG9zID0gYnVmZmVyOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA+IDEyNykgIC8qIGhleCBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChsZW4gPiAxICYmIHN0clsxXSA8IDEyOCAmJiBpc3hkaWdpdCgoY2hhcilzdHJbMV0pKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCUwNHgiLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHgleCIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyIDwgMzIpICAvKiBvY3RhbCBvciBDIGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEqc3RyICYmIGxlbiA9PSAxKSBjb250aW51ZTsgIC8qIGRvIG5vdCBvdXRwdXQgdGVybWluYXRpbmcgTlVMTCAqLwogICAgICAgICAgICBpZiAoZXNjYXBlc1sqc3RyXSAhPSAnLicpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlYyIsIGVzY2FwZXNbKnN0cl0gKTsKICAgICAgICAgICAgZWxzZSBpZiAobGVuID4gMSAmJiBzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8PSAnNycpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlMDNvIiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlbyIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID09ICdcXCcgfHwgKnN0ciA9PSBlc2NhcGVbMF0gfHwgKnN0ciA9PSBlc2NhcGVbMV0pICpwb3MrKyA9ICdcXCc7CiAgICAgICAgKnBvcysrID0gKnN0cjsKICAgIH0KICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgIHJldHVybiBjb3VudDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIGFuZCBkdW1wIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZHVtcF9zdHJBdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW4sRklMRSAqZixjaGFyIGVzY2FwZVsyXSkKewogICAgV0NIQVIgKnN0clc7CiAgICBpbnQgcmV0OwoKICAgIGlmIChzdHJBID09IE5VTEwpIHJldHVybiAwOwogICAgc3RyVyA9IF9zdHJkdXBuQXRvVyhzdHJBLGxlbik7CiAgICByZXQgPSBfZHVtcF9zdHJXKHN0clcsbGVuLGYsZXNjYXBlKTsKICAgIGZyZWUoc3RyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBhIGtleSB2YWx1ZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RydWN0IGtleV92YWx1ZSB7CiAgICBXQ0hBUiAgICAgICAgICAgICpuYW1lVzsgICAvKiB2YWx1ZSBuYW1lICovCiAgICBpbnQgICAgICAgICAgICAgICB0eXBlOyAgICAvKiB2YWx1ZSB0eXBlICovCiAgICBzaXplX3QgICAgICAgICAgICBsZW47ICAgICAvKiB2YWx1ZSBkYXRhIGxlbmd0aCBpbiBieXRlcyAqLwogICAgdm9pZCAgICAgICAgICAgICAqZGF0YTsgICAgLyogcG9pbnRlciB0byB2YWx1ZSBkYXRhICovCn07CgovKiBkdW1wIGEgdmFsdWUgdG8gYSB0ZXh0IGZpbGUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0YXRpYyB2b2lkIF9kdW1wX3ZhbHVlKHN0cnVjdCBrZXlfdmFsdWUgKnZhbHVlLEZJTEUgKmYpCnsKICAgIGludCBpLCBjb3VudDsKCiAgICBpZiAodmFsdWUtPm5hbWVXWzBdKSB7CiAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICBjb3VudCA9IDEgKyBfZHVtcF9zdHJXKHZhbHVlLT5uYW1lVyxzdHJsZW5XKHZhbHVlLT5uYW1lVyksZiwiXCJcIiIpOwogICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICJcIj0iICk7CiAgICB9CiAgICBlbHNlIGNvdW50ID0gZnByaW50ZiggZiwgIkA9IiApOwoKICAgIHN3aXRjaCh2YWx1ZS0+dHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgICBjYXNlIFJFR19NVUxUSV9TWjoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlICE9IFJFR19TWikgZnByaW50ZiggZiwgInN0ciglZCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgaWYgKHZhbHVlLT5kYXRhKSBfZHVtcF9zdHJXKHZhbHVlLT5kYXRhLHZhbHVlLT5sZW4vc2l6ZW9mKFdDSEFSKSxmLCJcIlwiIik7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0RXT1JEOgogICAgICAgICAgICBpZiAodmFsdWUtPmxlbiA9PSBzaXplb2YoRFdPUkQpKSB7CiAgICAgICAgICAgICAgICBEV09SRCBkdzsKICAgICAgICAgICAgICAgIG1lbWNweSggJmR3LCB2YWx1ZS0+ZGF0YSwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgICAgICAgICAgZnByaW50ZiggZiwgImR3b3JkOiUwOGx4IiwgZHcgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGVsc2UgZmFsbCB0aHJvdWdoICovCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlID09IFJFR19CSU5BUlkpIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXg6IiApOwogICAgICAgICAgICBlbHNlIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXgoJXgpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS0+bGVuOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICIlMDJ4IiwgKigodW5zaWduZWQgY2hhciAqKXZhbHVlLT5kYXRhICsgaSkgKTsKICAgICAgICAgICAgICAgIGlmIChpIDwgdmFsdWUtPmxlbi0xKSB7CiAgICAgICAgICAgICAgICAgICAgZnB1dGMoICcsJywgZiApOwogICAgICAgICAgICAgICAgICAgIGlmICgrK2NvdW50ID4gNzYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZiggZiwgIlxcXG4gICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwdXRjKCAnXG4nLCBmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewogICAgY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCiAgICB1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgIFtJbnRlcm5hbF0gKi8Kdm9pZCBfdzMxX2R1bXB0cmVlKHVuc2lnbmVkIHNob3J0IGlkeCx1bnNpZ25lZCBjaGFyICp0eHQsc3RydWN0IF93MzFfdGFiZW50ICp0YWIsc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLEhLRVkgaGtleSx0aW1lX3QgbGFzdG1vZGlmaWVkLCBpbnQgbGV2ZWwpCnsKICAgIHN0cnVjdCBfdzMxX2RpcmVudCAqZGlyOwogICAgc3RydWN0IF93MzFfa2V5ZW50ICprZXk7CiAgICBzdHJ1Y3QgX3czMV92YWxlbnQgKnZhbDsKICAgIEhLRVkgc3Via2V5ID0gMDsKICAgIHN0YXRpYyBjaGFyCXRhaWxbNDAwXTsKCiAgICB3aGlsZSAoaWR4IT0wKSB7CiAgICAgICAgZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCiAgICAgICAgaWYgKGRpci0+a2V5X2lkeCkgewogICAgICAgICAgICBrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgogICAgICAgICAgICBtZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwogICAgICAgICAgICB0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwogICAgICAgICAgICAvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAogICAgICAgICAgICAgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIWxldmVsICYmICFzdHJjbXAodGFpbCwiLmNsYXNzZXMiKSkgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgICAgICAgICAgaWYgKFJlZ0NyZWF0ZUtleUEoIGhrZXksIHRhaWwsICZzdWJrZXkgKSAhPSBFUlJPUl9TVUNDRVNTKSBzdWJrZXkgPSAwOwogICAgICAgICAgICAvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewogICAgICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwogICAgICAgICAgICAgICAgICAgIG1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZUEoIHN1YmtleSwgTlVMTCwgUkVHX1NaLCB0YWlsLCAwICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgVFJBQ0UoInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CiAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsc3Via2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgIH0KICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpIAp7CiAgICBIRklMRSBoZjsKICAgIHN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwogICAgc3RydWN0IF93MzFfdGFiZW50CSp0YWI7CiAgICB1bnNpZ25lZCBjaGFyCQkqdHh0OwogICAgdW5zaWduZWQgaW50CQlsZW47CiAgICBPRlNUUlVDVAkJb2ZzOwogICAgQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwogICAgdGltZV90CQkJbGFzdG1vZGlmaWVkOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CiAgICBpZiAoaGY9PUhGSUxFX0VSUk9SKSByZXR1cm47CgogICAgLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCiAgICBpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewogICAgICAgIEVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewogICAgICAgIEVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwogICAgLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwogICAgdGFiID0gX3htYWxsb2MobGVuKTsKICAgIGlmIChsZW4hPV9scmVhZChoZix0YWIsbGVuKSkgewogICAgICAgIEVSUigiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCiAgICAgICAgZnJlZSh0YWIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiByZWFkIHRleHQgKi8KICAgIHR4dCA9IF94bWFsbG9jKGhlYWQudGV4dHNpemUpOwogICAgaWYgKC0xPT1fbGxzZWVrKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKICAgICAgICBFUlIoImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZChoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKICAgICAgICBFUlIoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CiAgICAgICAgRVJSKCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwogICAgX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxIS0VZX0NMQVNTRVNfUk9PVCxsYXN0bW9kaWZpZWQsMCk7CiAgICBmcmVlKHRhYik7CiAgICBmcmVlKHR4dCk7CiAgICBfbGNsb3NlKGhmKTsKICAgIHJldHVybjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd3MgOTUgcmVnaXN0cnkgbG9hZGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIFNFQ1RJT04gMTogbWFpbiBoZWFkZXIKICoKICogb25jZSBhdCBvZmZzZXQgMAogKi8KI2RlZmluZQlXOTVfUkVHX0NSRUdfSUQJMHg0NzQ1NTI0MwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAiQ1JFRyIgPSBXOTVfUkVHX0NSRUdfSUQgKi8KICAgIERXT1JECXZlcnNpb247CS8qID8/Pz8gMHgwMDAxMDAwMCAqLwogICAgRFdPUkQJcmdkYl9vZmY7CS8qIDB4MDggT2Zmc2V0IG9mIDFzdCBSR0RCLWJsb2NrICovCiAgICBEV09SRAl1azI7CQkvKiAweDBjICovCiAgICBXT1JECXJnZGJfbnVtOwkvKiAweDEwICMgb2YgUkdEQi1ibG9ja3MgKi8KICAgIFdPUkQJdWszOwogICAgRFdPUkQJdWtbM107CiAgICAvKiByZ2tuICovCn0gX3c5NWNyZWc7CgovKiBTRUNUSU9OIDI6IERpcmVjdG9yeSBpbmZvcm1hdGlvbiAodHJlZSBzdHJ1Y3R1cmUpCiAqCiAqIG9uY2Ugb24gb2Zmc2V0IDB4MjAKICoKICogc3RydWN0dXJlOiBbcmdrbl1bZGtlXSoJKHJlcGVhdCB0aWxsIGxhc3RfZGtlIGlzIHJlYWNoZWQpCiAqLwojZGVmaW5lCVc5NV9SRUdfUkdLTl9JRAkweDRlNGI0NzUyCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIlJHS04iID0gVzk1X1JFR19SR0tOX0lEICovCiAgICBEV09SRAlzaXplOwkJLyogU2l6ZSBvZiB0aGUgUkdLTi1ibG9jayAqLwogICAgRFdPUkQJcm9vdF9vZmY7CS8qIFJlbC4gT2Zmc2V0IG9mIHRoZSByb290LXJlY29yZCAqLwogICAgRFdPUkQgICBsYXN0X2RrZTsgICAgICAgLyogT2Zmc2V0IHRvIGxhc3QgREtFID8gKi8KICAgIERXT1JECXVrWzRdOwp9IF93OTVyZ2tuOwoKLyogRGlzayBLZXkgRW50cnkgU3RydWN0dXJlCiAqCiAqIHRoZSAxc3QgZW50cnkgaW4gYSAidXN1YWwiIHJlZ2lzdHJ5IGZpbGUgaXMgYSBudWwtZW50cnkgd2l0aCBzdWJrZXlzOiB0aGUKICogaGl2ZSBpdHNlbGYuIEl0IGxvb2tzIHRoZSBzYW1lIGxpa2Ugb3RoZXIga2V5cy4gRXZlbiB0aGUgSUQtbnVtYmVyIGNhbgogKiBiZSBhbnkgdmFsdWUuCiAqCiAqIFRoZSAiaGFzaCItdmFsdWUgaXMgYSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGtleSdzIG5hbWUuIFdpbmRvd3Mgd2lsbCBub3QKICogc2VhcmNoIGZvciB0aGUgbmFtZSwgYnV0IGZvciBhIG1hdGNoaW5nIGhhc2gtdmFsdWUuIGlmIGl0IGZpbmRzIG9uZSwgaXQKICogd2lsbCBjb21wYXJlIHRoZSBhY3R1YWwgc3RyaW5nIGluZm8sIG90aGVyd2lzZSBjb250aW51ZSB3aXRoIHRoZSBuZXh0IGtleS4KICogVG8gY2FsY3VsYXRlIHRoZSBoYXNoIGluaXRpYWxpemUgYSBELVdvcmQgd2l0aCAwIGFuZCBhZGQgYWxsIEFTQ0lJLXZhbHVlcyAKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuICAgCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBTVFIga2V5X25hbWUsX3c5NWNyZWcgKmNyZWcsX3c5NXJna24gKnJna24sX3c5NWRrZSAqZGtlLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICBfdzk1ZGtoICogZGtoOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICAvKiBzcGVjaWFsIHJvb3Qga2V5ICovCiAgICBpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KICAgIHsKICAgICAgICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSAqLwogICAgICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgcmV0dXJuIF93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsKTsKICAgICAgICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNlYXJjaCBzdWJibG9jayAqLwogICAgaWYgKCEoZGtoID0gX3c5NV9sb29rdXBfZGtoKGNyZWcsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkpIHsKICAgICAgICBFUlIoImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkrZGtoLT5rZXluYW1lbGVuKzEpOwogICAgICAgIGlmIChzdHJjbXAobmV3X2tleV9uYW1lLCIiKSAhPSAwKSBzdHJjYXQobmV3X2tleV9uYW1lLCJcXCIpOwogICAgICAgIHN0cm5jYXQobmV3X2tleV9uYW1lLGRraC0+bmFtZSxka2gtPmtleW5hbWVsZW4pOwoKICAgICAgICAvKiB3YWxrIHNpYmxpbmcga2V5cyAqLwogICAgICAgIGlmIChka2UtPm5leHQgIT0gMHhmZmZmZmZmZiApIHsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dCksZixsZXZlbCkpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOiAKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChka2gtPnZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2Rrdihka2gsIGRrZS0+bnJMUywgZGtlLT5uck1TLGYpKSB7CiAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoKGRrZS0+bmV4dHN1YiA9PSAweGZmZmZmZmZmKSAmJiAoZGtoLT52YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpKTsKCiAgICAvKiBuZXh0IHN1YiBrZXkgKi8KICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgewogICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShuZXdfa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsLTEpKSB7CiAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9Ci8qIGVuZCB3aW5kb3dzIDk1IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd3MgTlQgcmVnaXN0cnkgbG9hZGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIE5UIFJFR0lTVFJZIExPQURFUiAqLwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2lmbmRlZiBNQVBfRkFJTEVECiNkZWZpbmUgTUFQX0ZBSUxFRCAoKExQVk9JRCktMSkKI2VuZGlmCgojZGVmaW5lIE5UX1JFR19CTE9DS19TSVpFICAgICAgICAgICAgMHgxMDAwCgojZGVmaW5lIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQgICAgICAgMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgTlRfUkVHX1BPT0xfQkxPQ0tfSUQgICAgICAgICAweDZFNjk2MjY4CS8qIGhiaW4gKi8KI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX0lEICAgICAgICAgIDB4NmI2ZSAvKiBuayAqLwojZGVmaW5lIE5UX1JFR19WQUxVRV9CTE9DS19JRCAgICAgICAgMHg2Yjc2IC8qIHZrICovCgovKiBzdWJibG9ja3Mgb2YgbmsgKi8KI2RlZmluZSBOVF9SRUdfSEFTSF9CTE9DS19JRCAgICAgICAgIDB4NjY2YyAvKiBsZiAqLwojZGVmaW5lIE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQgICAgICAgMHg2OTZjIC8qIGxpICovCiNkZWZpbmUgTlRfUkVHX1JJX0JMT0NLX0lECSAgICAgMHg2OTcyIC8qIHJpICovCgojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfVFlQRSAgICAgICAgMHgyMAojZGVmaW5lIE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFICAgMHgyYwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDY2Njc2NTcyICdyZWdmJyovCiAgICBEV09SRAl1azE7CQkvKiAweDA0ICovCiAgICBEV09SRAl1azI7CQkvKiAweDA4ICovCiAgICBGSUxFVElNRQlEYXRlTW9kaWZpZWQ7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXVrNTsJCS8qIDB4MWMgKi8KICAgIERXT1JECXVrNjsJCS8qIDB4MjAgKi8KICAgIERXT1JECVJvb3RLZXlCbG9jazsJLyogMHgyNCAqLwogICAgRFdPUkQJQmxvY2tTaXplOwkvKiAweDI4ICovCiAgICBEV09SRCAgIHVrN1sxMTZdOwkKICAgIERXT1JECUNoZWNrc3VtOyAvKiBhdCBvZmZzZXQgMHgxRkMgKi8KfSBudF9yZWdmOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJYmxvY2tzaXplOwogICAgQllURQlkYXRhWzFdOwp9IG50X2hiaW5fc3ViOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDZFNjk2MjY4ICdoYmluJyAqLwogICAgRFdPUkQJb2ZmX3ByZXY7CiAgICBEV09SRAlvZmZfbmV4dDsKICAgIERXT1JECXVrMTsKICAgIERXT1JECXVrMjsJCS8qIDB4MTAgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXNpemU7CQkvKiAweDFDICovCiAgICBudF9oYmluX3N1YgloYmluX3N1YjsJLyogMHgyMCAqLwp9IG50X2hiaW47CgovKgogKiB0aGUgdmFsdWVfbGlzdCBjb25zaXN0cyBvZiBvZmZzZXRzIHRvIHRoZSB2YWx1ZXMgKHZrKQogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlTdWJCbG9ja0lkOwkJLyogMHgwMCAweDZCNkUgKi8KICAgIFdPUkQJVHlwZTsJCQkvKiAweDAyIGZvciB0aGUgcm9vdC1rZXk6IDB4MkMsIG90aGVyd2lzZSAweDIwKi8KICAgIEZJTEVUSU1FCXdyaXRldGltZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkJCS8qIDB4MEMgKi8KICAgIERXT1JECXBhcmVudF9vZmY7CQkvKiAweDEwIE9mZnNldCBvZiBPd25lci9QYXJlbnQga2V5ICovCiAgICBEV09SRAlucl9zdWJrZXlzOwkJLyogMHgxNCBudW1iZXIgb2Ygc3ViLUtleXMgKi8KICAgIERXT1JECXVrODsJCQkvKiAweDE4ICovCiAgICBEV09SRAlsZl9vZmY7CQkJLyogMHgxQyBPZmZzZXQgb2YgdGhlIHN1Yi1rZXkgbGYtUmVjb3JkcyAqLwogICAgRFdPUkQJdWsyOwkJCS8qIDB4MjAgKi8KICAgIERXT1JECW5yX3ZhbHVlczsJCS8qIDB4MjQgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJdmFsdWVsaXN0X29mZjsJCS8qIDB4MjggT2Zmc2V0IG9mIHRoZSBWYWx1ZS1MaXN0ICovCiAgICBEV09SRAlvZmZfc2s7CQkJLyogMHgyYyBPZmZzZXQgb2YgdGhlIHNrLVJlY29yZCAqLwogICAgRFdPUkQJb2ZmX2NsYXNzOwkJLyogMHgzMCBPZmZzZXQgb2YgdGhlIENsYXNzLU5hbWUgKi8KICAgIERXT1JECXVrMzsJCQkvKiAweDM0ICovCiAgICBEV09SRAl1azQ7CQkJLyogMHgzOCAqLwogICAgRFdPUkQJdWs1OwkJCS8qIDB4M2MgKi8KICAgIERXT1JECXVrNjsJCQkvKiAweDQwICovCiAgICBEV09SRAl1azc7CQkJLyogMHg0NCAqLwogICAgV09SRAluYW1lX2xlbjsJCS8qIDB4NDggbmFtZS1sZW5ndGggKi8KICAgIFdPUkQJY2xhc3NfbGVuOwkJLyogMHg0YSBjbGFzcy1uYW1lIGxlbmd0aCAqLwogICAgY2hhcgluYW1lWzFdOwkJLyogMHg0YyBrZXktbmFtZSAqLwp9IG50X25rOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJb2ZmX25rOwkvKiAweDAwICovCiAgICBEV09SRAluYW1lOwkvKiAweDA0ICovCn0gaGFzaF9yZWM7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY2NmMgKi8KICAgIFdPUkQJbnJfa2V5czsJLyogMHgwNiAqLwogICAgaGFzaF9yZWMJaGFzaF9yZWNbMV07Cn0gbnRfbGY7CgovKgogbGlzdCBvZiBzdWJrZXlzIHdpdGhvdXQgaGFzaAoKIGxpIC0tKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NmMgKi8KICAgIFdPUkQJbnJfa2V5czsKICAgIERXT1JECW9mZl9ua1sxXTsKfSBudF9saTsKCi8qCiB0aGlzIGlzIGEgaW50ZXJtZWRpYXRlIG5vZGUKCiByaSAtLSstLT5saS0tKy0tPm5rCiAgICAgIHwgICAgICAgKwogICAgICB8ICAgICAgICstLT5uawogICAgICB8CiAgICAgICstLT5saS0tKy0tPm5rCiAgICAgICAgICAgICAgKwoJICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NzIgKi8KICAgIFdPUkQJbnJfbGk7CQkvKiAweDAyIG51bWJlciBvZmYgb2Zmc2V0cyAqLwogICAgRFdPUkQJb2ZmX2xpWzFdOwkvKiAweDA0IHBvaW50cyB0byBsaSAqLwp9IG50X3JpOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgJ3ZrJyAqLwogICAgV09SRAluYW1fbGVuOwogICAgRFdPUkQJZGF0YV9sZW47CiAgICBEV09SRAlkYXRhX29mZjsKICAgIERXT1JECXR5cGU7CiAgICBXT1JECWZsYWc7CiAgICBXT1JECXVrMTsKICAgIGNoYXIJbmFtZVsxXTsKfSBudF92azsKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X2R1bXBfdmsoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIG50X3ZrICp2ayxGSUxFICpmKQp7CiAgICBCWVRFICpwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCiAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwoKICAgIGlmICh2ay0+aWQgIT0gTlRfUkVHX1ZBTFVFX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIGJsb2NrIGZvdW5kICgweCUwNHgpLCBwbGVhc2UgcmVwb3J0IVxuIiwgdmstPmlkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1codmstPm5hbWUsdmstPm5hbV9sZW4pOwogICAgdmFsdWUudHlwZSA9IHZrLT50eXBlOwogICAgdmFsdWUubGVuID0gKHZrLT5kYXRhX2xlbiAmIDB4N2ZmZmZmZmYpOwogICAgdmFsdWUuZGF0YSA9ICh2ay0+ZGF0YV9sZW4gJiAweDgwMDAwMDAwKSA/IChMUEJZVEUpJih2ay0+ZGF0YV9vZmYpOiBwZGF0YTsKCiAgICBfZHVtcF92YWx1ZSgmdmFsdWUsZik7CiAgICBmcmVlKHZhbHVlLm5hbWVXKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyogaXQncyBjYWxsZWQgZnJvbSBfbnRfZHVtcF9sZigpICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBTVFIga2V5X25hbWUsY2hhciAqYmFzZSxudF9uayAqbmssRklMRSAqZixpbnQgbGV2ZWwpOwoKLyoKICogZ2V0IHRoZSBzdWJrZXlzCiAqCiAqIHRoaXMgc3RydWN0dXJlIGNvbnRhaW5zIHRoZSBoYXNoIG9mIGEga2V5bmFtZSBhbmQgcG9pbnRzIHRvIGFsbAogKiBzdWJrZXlzCiAqCiAqIGV4Y2VwdGlvbjogaWYgdGhlIGlkIGlzICdpbCcgdGhlcmUgYXJlIG5vIGhhc2ggdmFsdWVzIGFuZCBldmVyeSAKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X2R1bXBfbGYoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqbGYsIEZJTEUgKmYsIGludCBsZXZlbCkKewogICAgaW50IGk7CiAgICAKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CiAgICAKICAgICAgICBmb3IgKGk9MDsgaTxsZi0+bnJfa2V5czsgaSsrKSAKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsZi0+aGFzaF9yZWNbaV0ub2ZmX25rKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSB7CiAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopbGY7CiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGktPm5yX2tleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICBmb3IgKGk9MDsgaTxsaS0+bnJfa2V5czsgaSsrKQogICAgICAgICAgICBpZiAoIV9udF9kdW1wX25rKGtleV9uYW1lLCBiYXNlLCAobnRfbmsqKShiYXNlK2xpLT5vZmZfbmtbaV0rNCksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgIH0gZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19SSV9CTE9DS19JRCkgeyAgLyogcmkgKi8KICAgICAgICBudF9yaSAqIHJpID0gKG50X3JpKilsZjsKICAgICAgICBpbnQgbGlfc3Via2V5cyA9IDA7CgogICAgICAgIC8qIGNvdW50IGFsbCBzdWJrZXlzICovCiAgICAgICAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspIHsKICAgICAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYobGktPmlkICE9IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIGdvdG8gZXJyb3IyOwogICAgICAgICAgICBsaV9zdWJrZXlzICs9IGxpLT5ucl9rZXlzOwogICAgICAgIH0KCiAgICAgICAgLyogY2hlY2sgbnVtYmVyICovCiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGlfc3Via2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUga2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICpsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihrZXlfbmFtZSwgYmFzZSwgbGktPm5yX2tleXMsIChudF9sZiopbGksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgICAgICB9CiAgICB9IGVsc2UgZ290byBlcnJvcjI7CgogICAgcmV0dXJuIFRSVUU7CgplcnJvcjI6CiAgICBpZiAobGYtPmlkID09IDB4Njg2YykKICAgICAgICBGSVhNRSgidW5rbm93biBXaW4gWFAgbm9kZSBpZCAweDY4NmM6IGRvIHdlIG5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGl0ID9cbiIpOwogICAgZWxzZQogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIGxmLT5pZCk7CiAgICByZXR1cm4gVFJVRTsKCmVycm9yMToKICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISAoaW5jb25zaXN0ZW50IG51bWJlciBvZiBzdWJrZXlzKVxuIik7CiAgICByZXR1cm4gRkFMU0U7CgplcnJvcjoKICAgIEVSUigiZXJyb3IgcmVhZGluZyBsZiBibG9ja1xuIik7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qIF9udF9kdW1wX25rIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCkKewogICAgdW5zaWduZWQgaW50IG47CiAgICBEV09SRCAqdmw7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKCiAgICBpZiAobmstPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIG5rLT5TdWJCbG9ja0lkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChuay0+VHlwZSE9TlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpICYmICgoKG50X25rKikoYmFzZStuay0+cGFyZW50X29mZis0KSktPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkpIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpK25rLT5uYW1lX2xlbisxKTsKICAgICAgICBpZiAoc3RyY21wKG5ld19rZXlfbmFtZSwiIikgIT0gMCkgc3RyY2F0KG5ld19rZXlfbmFtZSwiXFwiKTsKICAgICAgICBzdHJuY2F0KG5ld19rZXlfbmFtZSxuay0+bmFtZSxuay0+bmFtZV9sZW4pOwoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6IAogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKG5rLT5ucl92YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgICAgICBpZiAoKG5rLT5ucl9zdWJrZXlzID09IDApICYmIChuay0+bnJfdmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KCiAgICAgICAgLyogbG9vcCB0cm91Z2ggdGhlIHZhbHVlIGxpc3QgKi8KICAgICAgICB2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwogICAgICAgIGZvciAobj0wOyBuPG5rLT5ucl92YWx1ZXM7IG4rKykgewogICAgICAgICAgICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtuXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF92ayhuZXdfa2V5X25hbWUsIGJhc2UsIHZrLCBmKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpKTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KICAgIGlmIChuay0+bnJfc3Via2V5cykgewogICAgICAgIG50X2xmICpsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKICAgICAgICBpZiAoIV9udF9kdW1wX2xmKG5ld19rZXlfbmFtZSwgYmFzZSwgbmstPm5yX3N1YmtleXMsIGxmLCBmLCBsZXZlbC0xKSkgewogICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zZXRfcmVnaXN0cnlfbGV2ZWxzIFtJbnRlcm5hbF0KICoKICogc2V0IGxldmVsIHRvIDAgZm9yIGxvYWRpbmcgc3lzdGVtIGZpbGVzCiAqIHNldCBsZXZlbCB0byAxIGZvciBsb2FkaW5nIHVzZXIgZmlsZXMKICovCnN0YXRpYyB2b2lkIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKGludCBsZXZlbCxpbnQgc2F2aW5nLGludCBwZXJpb2QpCnsKICAgIFNFUlZFUl9TVEFSVF9SRVEoIHNldF9yZWdpc3RyeV9sZXZlbHMgKQogICAgewoJcmVxLT5jdXJyZW50ID0gbGV2ZWw7CglyZXEtPnNhdmluZyAgPSBzYXZpbmc7CiAgICAgICAgcmVxLT5wZXJpb2QgID0gcGVyaW9kOwogICAgICAgIHdpbmVfc2VydmVyX2NhbGwoIHJlcSApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7Cn0KCi8qIF9zYXZlX2F0X2V4aXQgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfc2F2ZV9hdF9leGl0KEhLRVkgaGtleSxMUENTVFIgcGF0aCkKewogICAgTFBDU1RSIGNvbmZkaXIgPSBnZXRfY29uZmlnX2RpcigpOwoKICAgIFNFUlZFUl9TVEFSVF9SRVEoIHNhdmVfcmVnaXN0cnlfYXRleGl0ICkKICAgIHsKICAgICAgICByZXEtPmhrZXkgPSBoa2V5OwogICAgICAgIHdpbmVfc2VydmVyX2FkZF9kYXRhKCByZXEsIGNvbmZkaXIsIHN0cmxlbihjb25mZGlyKSApOwogICAgICAgIHdpbmVfc2VydmVyX2FkZF9kYXRhKCByZXEsIHBhdGgsIHN0cmxlbihwYXRoKSsxICk7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyogY29uZmlndXJlIHNhdmUgZmlsZXMgYW5kIHN0YXJ0IHRoZSBwZXJpb2RpYyBzYXZpbmcgdGltZXIgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfaW5pdF9yZWdpc3RyeV9zYXZpbmcoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IGFsbDsKICAgIGludCBwZXJpb2Q7CgogICAgYWxsICA9IFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiU2F2ZU9ubHlVcGRhdGVkS2V5cyIsMSk7CiAgICBwZXJpb2QgPSBQUk9GSUxFX0dldFdpbmVJbmlJbnQoInJlZ2lzdHJ5IiwiUGVyaW9kaWNTYXZlIiwwKTsKCiAgICAvKiBzZXQgc2F2aW5nIGxldmVsICgwIGZvciBzYXZpbmcgZXZlcnl0aGluZywgMSBmb3Igc2F2aW5nIG9ubHkgbW9kaWZpZWQga2V5cykgKi8KICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDEsIWFsbCxwZXJpb2QqMTAwMCk7CgogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiV3JpdGV0b0hvbWVSZWdpc3RyeUZpbGVzIiwxKSkKICAgIHsKICAgICAgICBfc2F2ZV9hdF9leGl0KEhLRVlfQ1VSUkVOVF9VU0VSLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KEhLRVlfTE9DQUxfTUFDSElORSwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICAgICAgX3NhdmVfYXRfZXhpdChoa2V5X3VzZXJzX2RlZmF1bHQsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICB9Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLiAKICovCnN0YXRpYyB2b2lkIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXModm9pZCkgewoJSEtFWQloa2V5OwoJY2hhcglidWZbMjAwXTsKCglUUkFDRSgiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXlBKEhLRVlfRFlOX0RBVEEsIlBlcmZTdGF0c1xcU3RhdERhdGEiLCZoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgICAgICAvKiBUaGlzIHdhcyBhbiBPcGVuLCBidXQgc2luY2UgaXQgaXMgY2FsbGVkIGJlZm9yZSB0aGUgcmVhbCByZWdpc3RyaWVzCiAgICAgICAgICAgYXJlIGxvYWRlZCwgaXQgd2FzIGNoYW5nZWQgdG8gYSBDcmVhdGUgLSBNVEIgOTgwNTA3Ki8KCVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbSIsJmhrZXkpOwoJUmVnU2V0VmFsdWVFeEEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvd3MgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8KCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4QShoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCiAgICAgICAgUmVnQ3JlYXRlS2V5QShIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwp9CgojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgICAgMAojZGVmaW5lIFJFR19XSU45NSAgICAgMQojZGVmaW5lIFJFR19XSU5OVCAgICAgMgoKLyogcmV0dXJuIHRoZSB0eXBlIG9mIG5hdGl2ZSByZWdpc3RyeSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF9yZWdfdHlwZSh2b2lkKQp7CiAgICBjaGFyIHdpbmRpcltNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGNoYXIgdG1wW01BWF9QQVRITkFNRV9MRU5dOwogICAgaW50IHJldCA9IFJFR19XSU4zMTsKCiAgICBHZXRXaW5kb3dzRGlyZWN0b3J5QSh3aW5kaXIsTUFYX1BBVEhOQU1FX0xFTik7CgogICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0zMi9jb25maWcvc3lzdGVtIC0tPiB3aW5udCAqLwogICAgc3RyY3B5KHRtcCwgd2luZGlyKTsKICAgIHN0cm5jYXQodG1wLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzeXN0ZW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHRtcCkgLSAxKTsKICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQSh0bXApICE9IChEV09SRCktMSkgewogICAgICByZXQgPSBSRUdfV0lOTlQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbS5kYXQgLS0+IHdpbjk1ICovCiAgICAgIHN0cmNweSh0bXAsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQodG1wLCAiXFxzeXN0ZW0uZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbih0bXApIC0gMSk7CiAgICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQSh0bXApICE9IChEV09SRCktMSkgewogICAgICAgIHJldCA9IFJFR19XSU45NTsKICAgICAgfQogICAgfQoKICAgIGlmICgocmV0ID09IFJFR19XSU5OVCkgJiYgKCFQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgdG1wLCBNQVhfUEFUSE5BTUVfTEVOKSkpIHsKICAgICAgIE1FU1NBR0UoIldoZW4geW91IGFyZSBydW5uaW5nIHdpdGggYSBuYXRpdmUgTlQgZGlyZWN0b3J5IHNwZWNpZnlcbiIpOwogICAgICAgTUVTU0FHRSgiJ1Byb2ZpbGU9PHByb2ZpbGVkaXJlY3Rvcnk+JyBvciBkaXNhYmxlIGxvYWRpbmcgb2YgV2luZG93c1xuIik7CiAgICAgICBNRVNTQUdFKCJyZWdpc3RyeSAoTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzPU4pXG4iKTsKICAgICAgIHJldCA9IFJFR19ET05UTE9BRDsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgojZGVmaW5lIFdJTkVfUkVHX1ZFUl9FUlJPUiAgLTEKI2RlZmluZSBXSU5FX1JFR19WRVJfMSAgICAgICAwCiNkZWZpbmUgV0lORV9SRUdfVkVSXzIgICAgICAgMQojZGVmaW5lIFdJTkVfUkVHX1ZFUl9PTEQgICAgIDIKI2RlZmluZSBXSU5FX1JFR19WRVJfVU5LTk9XTiAzCgovKiByZXR1cm4gdGhlIHZlcnNpb24gb2Ygd2luZSByZWdpc3RyeSBmaWxlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZ2V0X3dpbmVfcmVnaXN0cnlfZmlsZV9mb3JtYXRfdmVyc2lvbihMUENTVFIgZm4pCnsKICAgIEZJTEUgKmY7CiAgICBjaGFyIHRtcFs1MF07CiAgICBpbnQgdmVyOwoKICAgIGlmICgoZj1mb3BlbihmbiwicnQiKSkgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9FUlJPUjsKICAgIH0KCiAgICBpZiAoZmdldHModG1wLDUwLGYpID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJFcnJvciByZWFkaW5nICVzOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykpOwogICAgICAgIGZjbG9zZShmKTsKICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSX0VSUk9SOwogICAgfQogICAgZmNsb3NlKGYpOwoKICAgIGlmIChzc2NhbmYodG1wLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiLCZ2ZXIpICE9IDEpIHJldHVybiBXSU5FX1JFR19WRVJfVU5LTk9XTjsKICAgIHN3aXRjaCAodmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSXzE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl8yOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSX1VOS05PV047CiAgICB9Cn0KCi8qIGxvYWQgdGhlIHJlZ2lzdHJ5IGZpbGUgaW4gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBsb2FkX3dpbmVfcmVnaXN0cnkoSEtFWSBoa2V5LExQQ1NUUiBmbikKewogICAgaW50IGZpbGVfZm9ybWF0OwoKICAgIGZpbGVfZm9ybWF0ID0gX2dldF93aW5lX3JlZ2lzdHJ5X2ZpbGVfZm9ybWF0X3ZlcnNpb24oZm4pOwogICAgc3dpdGNoIChmaWxlX2Zvcm1hdCkgewoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl8xOgogICAgICAgICAgICBXQVJOKCJVbmFibGUgdG8gbG9hZCByZWdpc3RyeSBmaWxlICVzOiBvbGQgZm9ybWF0IHdoaWNoIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuXG4iLGZuKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSXzI6IHsKICAgICAgICAgICAgSEFORExFIGZpbGU7CiAgICAgICAgICAgIGlmICgoZmlsZSA9IEZJTEVfQ3JlYXRlRmlsZSggZm4sIEdFTkVSSUNfUkVBRCwgMCwgTlVMTCwgT1BFTl9FWElTVElORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgMCwgVFJVRSwgRFJJVkVfVU5LTk9XTiApKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF9yZWdpc3RyeSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5oa2V5ICAgID0gaGtleTsKICAgICAgICAgICAgICAgICAgICByZXEtPmZpbGUgICAgPSBmaWxlOwogICAgICAgICAgICAgICAgICAgIHdpbmVfc2VydmVyX2NhbGwoIHJlcSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggZmlsZSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfVU5LTk9XTjoKICAgICAgICAgICAgV0FSTigiVW5hYmxlIHRvIGxvYWQgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBmb3JtYXQuXG4iLGZuKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSX0VSUk9SOgogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKLyogZ2VuZXJhdGUgYW5kIHJldHVybiB0aGUgbmFtZSBvZiB0aGUgdG1wIGZpbGUgYW5kIGFzc29jaWF0ZWQgc3RyZWFtIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9nZXRfdG1wX2ZuKEZJTEUgKipmKQp7CiAgICBMUFNUUiByZXQ7CiAgICBpbnQgdG1wX2ZkLGNvdW50OwoKICAgIHJldCA9IF94bWFsbG9jKDUwKTsKICAgIGZvciAoY291bnQgPSAwOzspIHsKICAgICAgICBzcHJpbnRmKHJldCwiL3RtcC9yZWclbHglMDR4LnRtcCIsKGxvbmcpZ2V0cGlkKCksY291bnQrKyk7CiAgICAgICAgaWYgKCh0bXBfZmQgPSBvcGVuKHJldCxPX0NSRUFUIHwgT19FWENMIHwgT19XUk9OTFksMDY2NikpICE9IC0xKSBicmVhazsKICAgICAgICBpZiAoZXJybm8gIT0gRUVYSVNUKSB7CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgZnJlZShyZXQpOwogICAgICAgICAgICAqZiA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKCpmID0gZmRvcGVuKHRtcF9mZCwidyIpKSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIGZkb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgY2xvc2UodG1wX2ZkKTsKICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW45NSBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENTVFIgZm4saW50IGxldmVsKQp7CiAgICBpbnQgZmQ7CiAgICBGSUxFICpmOwogICAgRE9TX0ZVTExfTkFNRSBmdWxsX25hbWU7CiAgICB2b2lkICpiYXNlOwogICAgTFBTVFIgcmV0ID0gTlVMTDsKICAgIHN0cnVjdCBzdGF0IHN0OwoKICAgIF93OTVjcmVnICpjcmVnOwogICAgX3c5NXJna24gKnJna247CiAgICBfdzk1ZGtlICpka2UsICpyb290X2RrZTsKCiAgICBpZiAoIURPU0ZTX0dldEZ1bGxOYW1lKCBmbiwgMCwgJmZ1bGxfbmFtZSApKSByZXR1cm4gTlVMTDsKCiAgICAvKiBtYXAgdGhlIHJlZ2lzdHJ5IGludG8gdGhlIG1lbW9yeSAqLwogICAgaWYgKChmZCA9IG9wZW4oZnVsbF9uYW1lLmxvbmdfbmFtZSwgT19SRE9OTFkgfCBPX05PTkJMT0NLKSkgPT0gLTEpIHJldHVybiBOVUxMOwogICAgaWYgKChmc3RhdChmZCwgJnN0KSA9PSAtMSkpIGdvdG8gZXJyb3IxOwogICAgaWYgKCFzdC5zdF9zaXplKSBnb3RvIGVycm9yMTsKICAgIGlmICgoYmFzZSA9IG1tYXAoTlVMTCwgc3Quc3Rfc2l6ZSwgUFJPVF9SRUFELCBNQVBfUFJJVkFURSwgZmQsIDApKSA9PSBNQVBfRkFJTEVEKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IFc5NV9SRUdfQ1JFR19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIixmbik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBjcmVnID0gYmFzZTsKICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CiAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSB7CiAgICAgICAgRVJSKCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVseFxuIiwgcmdrbi0+aWQpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+cm9vdF9vZmYgIT0gMHgyMCkgewogICAgICAgIEVSUigicmdrbi0+cm9vdF9vZmYgbm90IDB4MjAsIHBsZWFzZSByZXBvcnQgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5sYXN0X2RrZSA+IHJna24tPnNpemUpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBsYXN0X2RrZSA+IHNpemUhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIC8qIHZlcmlmeSBsYXN0IGRrZSAqLwogICAgZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPmxhc3RfZGtlKTsKICAgIGlmIChka2UtPngxICE9IDB4ODAwMDAwMDApCiAgICB7IC8qIHdyb25nIG1hZ2ljICovCiAgICAgIEVSUigibGFzdCBka2UgaW52YWxpZCAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5zaXplID4gY3JlZy0+cmdkYl9vZmYpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZ2tuIHNpemUgPiByZ2RiX29mZiAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIHJvb3RfZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPnJvb3Rfb2ZmKTsKICAgIGlmICggKHJvb3RfZGtlLT5wcmV2bHZsICE9IDB4ZmZmZmZmZmYpIHx8IChyb290X2RrZS0+bmV4dCAhPSAweGZmZmZmZmZmKSApCiAgICB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGludmFsaWQgcm9vdCBka2UgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfdzk1X2R1bXBfZGtlKCIiLGNyZWcscmdrbixyb290X2RrZSxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgaWYocmV0ID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzLlxuIixmbik7CiAgICAgICAgRVJSKCJQbGVhc2UgcmVwb3J0IHRvIGEubW9ockBtYWlsdG8uZGUuXG4iKTsKICAgICAgICBFUlIoIk1ha2UgYSBiYWNrdXAgb2YgdGhlIGZpbGUsIHJ1biBhIGdvb2QgcmVnIGNsZWFuZXIgcHJvZ3JhbSBhbmQgdHJ5IGFnYWluIVxuIik7CiAgICB9CgogICAgbXVubWFwKGJhc2UsIHN0LnN0X3NpemUpOwplcnJvcjE6CiAgICBjbG9zZShmZCk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbm50IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1NUUiBmbixpbnQgbGV2ZWwpCnsKICAgIGludCBmZDsKICAgIEZJTEUgKmY7CiAgICBET1NfRlVMTF9OQU1FIGZ1bGxfbmFtZTsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgc3RydWN0IHN0YXQgc3Q7CgogICAgbnRfcmVnZiAqcmVnZjsKICAgIG50X2hiaW4gKmhiaW47CiAgICBudF9oYmluX3N1YiAqaGJpbl9zdWI7CiAgICBudF9uayAqbms7CgogICAgaWYgKCFET1NGU19HZXRGdWxsTmFtZSggZm4sIDAsICZmdWxsX25hbWUgKSkgcmV0dXJuIE5VTEw7CgogICAgLyogbWFwIHRoZSByZWdpc3RyeSBpbnRvIHRoZSBtZW1vcnkgKi8KICAgIGlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gTlVMTDsKICAgIGlmICgoZnN0YXQoZmQsICZzdCkgPT0gLTEpKSBnb3RvIGVycm9yMTsKICAgIGlmICghc3Quc3Rfc2l6ZSkgZ290byBlcnJvcjE7CiAgICBpZiAoKGJhc2UgPSBtbWFwKE5VTEwsIHN0LnN0X3NpemUsIFBST1RfUkVBRCwgTUFQX1BSSVZBVEUsIGZkLCAwKSkgPT0gTUFQX0ZBSUxFRCkgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2lubnQgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLGZuKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIHN0YXJ0IGJsb2NrICovCiAgICByZWdmID0gYmFzZTsKCiAgICAvKiBoYmluIGJsb2NrICovCiAgICBoYmluID0gKG50X2hiaW4qKSgoY2hhciopIGJhc2UgKyAweDEwMDApOwogICAgaWYgKGhiaW4tPmlkICE9IE5UX1JFR19QT09MX0JMT0NLX0lEKSB7CiAgICAgIEVSUiggImhiaW4gYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkgewogICAgICBFUlIoICJoYmluX3N1YiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBuayBibG9jayAqLwogICAgbmsgPSAobnRfbmsqKSYoaGJpbl9zdWItPmRhdGFbMF0pOwogICAgaWYgKG5rLT5UeXBlICE9IE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSB7CiAgICAgIEVSUiggInNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfbnRfZHVtcF9uaygiIiwoY2hhciopYmFzZSsweDEwMDAsbmssZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIG11bm1hcChiYXNlLHN0LnN0X3NpemUpOwplcnJvcjE6CiAgICBjbG9zZShmZCk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IG5hdGl2ZSByZWdpc3RyeSB0byB3aW5lIGZvcm1hdCBhbmQgbG9hZCBpdCB2aWEgc2VydmVyIGNhbGwgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoTFBDU1RSIGZuLEhLRVkgaGtleSxpbnQgcmVnX3R5cGUsaW50IGxldmVsKQp7CiAgICBMUFNUUiB0bXAgPSBOVUxMOwoKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDoKICAgICAgICAgICAgLyogRklYTUU6IGZvbGxvd2luZyBmdW5jdGlvbiBkb2Vzbid0IHJlYWxseSBjb252ZXJ0IHlldCAqLwogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICAgICAgICBFUlIoIkRvbid0IGtub3cgaG93IHRvIGNvbnZlcnQgbmF0aXZlIDMuMSByZWdpc3RyeSB5ZXQuXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmtub3duIHJlZ2lzdHJ5IGZvcm1hdCBwYXJhbWV0ZXIgKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmICh0bXAgIT0gTlVMTCkgewogICAgICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5LHRtcCk7CiAgICAgICAgVFJBQ0UoIkZpbGUgJXMgc3VjY2Vzc2Z1bGx5IGNvbnZlcnRlZCB0byAlcyBhbmQgbG9hZGVkIHRvIHJlZ2lzdHJ5LlxuIixmbix0bXApOwogICAgICAgIHVubGluayh0bXApOwogICAgfQogICAgZWxzZSBXQVJOKCJVbmFibGUgdG8gY29udmVydCAlcyAoZG9lc24ndCBleGlzdD8pXG4iLGZuKTsKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgbmF0aXZlIHdpbmRvd3MgcmVnaXN0cnkgZmlsZXMgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIGludCByZWdfdHlwZTsKICAgIGNoYXIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogICAgY2hhciBwYXRoW01BWF9QQVRITkFNRV9MRU5dOwoKICAgIEdldFdpbmRvd3NEaXJlY3RvcnlBKHdpbmRpcixNQVhfUEFUSE5BTUVfTEVOKTsKCiAgICByZWdfdHlwZSA9IF9nZXRfcmVnX3R5cGUoKTsKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDogewogICAgICAgICAgICBIS0VZIGhrZXk7CgogICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIG50dXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkgewogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcbnR1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxkZWZhdWx0Iik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAqIEZJWE1FCiAgICAgICAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNZU1RFTSIsICZoa2V5KSkgewoJICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKCSAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIpOwogICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU09GVFdBUkUiLCAmaGtleSkpIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzb2Z0d2FyZSIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2FtIik7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzZWN1cml0eSIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXENsb25lIiwmaGtleSkpIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoImM6XFxzeXN0ZW0uMXN0IixIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtLmRhdCIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygiV2luZSIsIlByb2ZpbGUiLCIiLHBhdGgsTUFYX1BBVEhOQU1FX0xFTikpIHsKCSAgICAgICAgLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwoJICAgICAgICBzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTjk1LDEpOwoKCSAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwoJICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFx1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcdXNlci5kYXQiKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfQ1VSUkVOVF9VU0VSLFJFR19XSU45NSwxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIC8qIEZJWE1FOiBoZXJlIHdlIHNob3VsZCBjb252ZXJ0IHRvICoucmVnIGZpbGUgc3VwcG9ydGVkIGJ5IHNlcnZlciBhbmQgY2FsbCBSRVFfTE9BRF9SRUdJU1RSWSwgc2VlIFJFR19XSU45NSBjYXNlICovCiAgICAgICAgICAgIF93MzFfbG9hZHJlZygpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfRE9OVExPQUQ6CiAgICAgICAgICAgIFRSQUNFKCJSRUdfRE9OVExPQURcbiIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzd2l0Y2g6IG5vIG1hdGNoICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKCiAgICB9Cn0KCi8qIGxvYWQgZ2xvYmFsIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gL2V0Yy93aW5lKSBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX2dsb2JhbF9yZWdpc3RyeSh2b2lkKQp7CiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICAvKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIEhLRVlfVVNFUlMsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgKTsKCiAgICAvKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgIGxvYWRfd2luZV9yZWdpc3RyeSggSEtFWV9MT0NBTF9NQUNISU5FLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSApOwp9CgovKiBsb2FkIGhvbWUgcmVnaXN0cnkgZmlsZXMgKHN0b3JlZCBpbiB+Ly53aW5lKSBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX2hvbWVfcmVnaXN0cnkoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgTFBDU1RSIGNvbmZkaXIgPSBnZXRfY29uZmlnX2RpcigpOwogICAgTFBTVFIgdG1wID0gX3htYWxsb2Moc3RybGVuKGNvbmZkaXIpKzIwKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5X3VzZXJzX2RlZmF1bHQsdG1wKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZX0NVUlJFTlRfVVNFUix0bXApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZX0xPQ0FMX01BQ0hJTkUsdG1wKTsKCiAgICBmcmVlKHRtcCk7Cn0KCi8qIGxvYWQgYWxsIHJlZ2lzdHJ5IChuYXRpdmUgYW5kIGdsb2JhbCBhbmQgaG9tZSkgKi8Kdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgICBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdDsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBpZiAoIUNMSUVOVF9Jc0Jvb3RUaHJlYWQoKSkgcmV0dXJuOyAgLyogYWxyZWFkeSBsb2FkZWQgKi8KCiAgICBpZiAoUmVnQ3JlYXRlS2V5QShIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXlfdXNlcnNfZGVmYXVsdCkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIEhLRVlfVVNFUlMvLkRlZmF1bHRcbiIgKTsKICAgICAgICBFeGl0UHJvY2VzcygxKTsKICAgIH0KCiAgICBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKCk7CiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygwLDAsMCk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXMiLDEpKQogICAgICAgIF9sb2FkX3dpbmRvd3NfcmVnaXN0cnkoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woIlJlZ2lzdHJ5IiwiTG9hZEdsb2JhbFJlZ2lzdHJ5RmlsZXMiLDEpKQogICAgICAgIF9sb2FkX2dsb2JhbF9yZWdpc3RyeSgpOwogICAgX3NldF9yZWdpc3RyeV9sZXZlbHMoMSwwLDApOwogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woIlJlZ2lzdHJ5IiwiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwxKSkKICAgICAgICBfbG9hZF9ob21lX3JlZ2lzdHJ5KCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICAgIF9pbml0X3JlZ2lzdHJ5X3NhdmluZyggaGtleV91c2Vyc19kZWZhdWx0ICk7CiAgICBSZWdDbG9zZUtleShoa2V5X3VzZXJzX2RlZmF1bHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgQVBJIEZVTkNUSU9OUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbQURWQVBJMzIuQF0KICogSW1tZWRpYXRlbHkgd3JpdGVzIGtleSB0byByZWdpc3RyeS4KICogT25seSByZXR1cm5zIGFmdGVyIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiB0byBkaXNrLgogKgogKiBGSVhNRTogZG9lcyBpdCByZWFsbHkgd2FpdCB1bnRpbCBkYXRhIGlzIHdyaXR0ZW4gPwogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBGSVhNRSggIigleCk6IHN0dWJcbiIsIGhrZXkgKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXlBIFtBRFZBUEkzMi5AXQogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXkgKQp7CiAgICBGSVhNRSgiKCV4LCVzKTogc3R1YlxuIixoa2V5LCBkZWJ1Z3N0cl9hKGxwU3ViS2V5KSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleUEgW0FEVkFQSTMyLkBdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBGSVhNRSgiKCV4LCVzLCVzLCVzKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfYShscFN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl9hKGxwTmV3RmlsZSksZGVidWdzdHJfYShscE9sZEZpbGUpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKCgoKCi8qIDE2LWJpdCBmdW5jdGlvbnMgKi8KCi8qIDAgYW5kIDEgYXJlIHZhbGlkIHJvb3RrZXlzIGluIHdpbjE2IHNoZWxsLmRsbCBhbmQgYXJlIHVzZWQgYnkKICogc29tZSBwcm9ncmFtcy4gRG8gbm90IHJlbW92ZSB0aG9zZSBjYXNlcy4gLU1NCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZml4X3dpbjE2X2hrZXkoIEhLRVkgKmhrZXkgKQp7CiAgICBpZiAoKmhrZXkgPT0gMCB8fCAqaGtleSA9PSAxKSAqaGtleSA9IEhLRVlfQ0xBU1NFU19ST09UOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdFbnVtS2V5ICAgW0tFUk5FTC4yMTZdCiAqICAgICAgICAgICBSZWdFbnVtS2V5ICAgW1NIRUxMLjddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGluZGV4LCBMUFNUUiBuYW1lLCBEV09SRCBuYW1lX2xlbiApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0VudW1LZXlBKCBoa2V5LCBpbmRleCwgbmFtZSwgbmFtZV9sZW4gKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnT3BlbktleSAgIFtLRVJORUwuMjE3XQogKiAgICAgICAgICAgUmVnT3BlbktleSAgIFtTSEVMTC4xXQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBIS0VZIHJldGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ09wZW5LZXlBKCBoa2V5LCBuYW1lLCByZXRrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnQ3JlYXRlS2V5ICAgW0tFUk5FTC4yMThdCiAqICAgICAgICAgICBSZWdDcmVhdGVLZXkgICBbU0hFTEwuMl0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBIS0VZIHJldGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0NyZWF0ZUtleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVLZXkgICBbS0VSTkVMLjIxOV0KICogICAgICAgICAgIFJlZ0RlbGV0ZUtleSAgIFtTSEVMTC40XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDbG9zZUtleSAgIFtLRVJORUwuMjIwXQogKiAgICAgICAgICAgUmVnQ2xvc2VLZXkgICBbU0hFTEwuM10KICovCkRXT1JEIFdJTkFQSSBSZWdDbG9zZUtleTE2KCBIS0VZIGhrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdDbG9zZUtleSggaGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZSAgIFtLRVJORUwuMjIxXQogKiAgICAgICAgICAgUmVnU2V0VmFsdWUgICBbU0hFTEwuNV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBEV09SRCB0eXBlLCBMUENTVFIgZGF0YSwgRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUEoIGhrZXksIG5hbWUsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZVZhbHVlICBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bVZhbHVlICAgW0tFUk5FTC4yMjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIHZhbHVlLCBMUERXT1JEIHZhbF9jb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bVZhbHVlQSggaGtleSwgaW5kZXgsIHZhbHVlLCB2YWxfY291bnQsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlICAgW0tFUk5FTC4yMjRdCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlICAgW1NIRUxMLjZdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBTVFIgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgaWYgKGNvdW50KSAqY291bnQgJj0gMHhmZmZmOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVBKCBoa2V5LCBuYW1lLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlRXggICBbS0VSTkVMLjIyNV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBEV09SRCByZXNlcnZlZCwgTFBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUV4QSggaGtleSwgbmFtZSwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlRXggICBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHJlc2VydmVkLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBCWVRFICpkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgaWYgKCFjb3VudCAmJiAodHlwZT09UkVHX1NaKSkgY291bnQgPSBzdHJsZW4oZGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdGbHVzaEtleSAgIFtLRVJORUwuMjI3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0ZsdXNoS2V5KCBoa2V5ICk7Cn0K