LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxmY250bC5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbm50LmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9saWJyYXJ5LmgiCiNpbmNsdWRlICJ3aW5lL3NlcnZlci5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJmaWxlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocmVnKTsKCi8qIEZJWE1FOiBmb2xsb3dpbmcgZGVmaW5lcyBzaG91bGQgYmUgY29uZmlndXJlZCBnbG9iYWwgKi8KI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICBFVENESVIiL3dpbmUudXNlcnJlZyIKI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgICJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgICJ1c2VyZGVmLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FICJzeXN0ZW0ucmVnIgoKLyogX3htYWxsb2MgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCAqX3htYWxsb2MoIHNpemVfdCBzaXplICkKewogICAgdm9pZCAqcmVzOwoKICAgIHJlcyA9IG1hbGxvYyAoc2l6ZSA/IHNpemUgOiAxKTsKICAgIGlmIChyZXMgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIlZpcnR1YWwgbWVtb3J5IGV4aGF1c3RlZC5cbiIpOwogICAgICAgIGV4aXQgKDEpOwogICAgfQogICAgcmV0dXJuIHJlczsKfQoKLyogX3N0cmR1cG5BIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9zdHJkdXBuQShMUENTVFIgc3RyLHNpemVfdCBsZW4pCnsKICAgIExQU1RSIHJldDsKCiAgICBpZiAoIXN0cikgcmV0dXJuIE5VTEw7CiAgICByZXQgPSBfeG1hbGxvYyggbGVuICsgMSApOwogICAgbWVtY3B5KCByZXQsIHN0ciwgbGVuICk7CiAgICByZXRbbGVuXSA9IDB4MDA7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBXU1RSIF9zdHJkdXBuQXRvVyhMUENTVFIgc3RyQSxzaXplX3QgbGVuQSkKewogICAgTFBXU1RSIHJldDsKICAgIHNpemVfdCBsZW5XOwoKICAgIGlmICghc3RyQSkgcmV0dXJuIE5VTEw7CiAgICBsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsMCxzdHJBLGxlbkEsTlVMTCwwKTsKICAgIHJldCA9IF94bWFsbG9jKGxlblcqc2l6ZW9mKFdDSEFSKStzaXplb2YoV0NIQVIpKTsKICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLDAsc3RyQSxsZW5BLHJldCxsZW5XKTsKICAgIHJldFtsZW5XXSA9IDA7CiAgICByZXR1cm4gcmV0Owp9CgovKiBkdW1wIGEgVW5pY29kZSBzdHJpbmcgd2l0aCBwcm9wZXIgZXNjYXBpbmcgW0ludGVybmFsXSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3VuaWNvZGUuYyAqLwpzdGF0aWMgaW50IF9kdW1wX3N0clcoY29uc3QgV0NIQVIgKnN0cixzaXplX3QgbGVuLEZJTEUgKmYsY2hhciBlc2NhcGVbMl0pCnsKICAgIHN0YXRpYyBjb25zdCBjaGFyIGVzY2FwZXNbMzJdID0gIi4uLi4uLi5hYnRudmZyLi4uLi4uLi4uLi4uLmUuLi4uIjsKICAgIGNoYXIgYnVmZmVyWzI1Nl07CiAgICBMUFNUUiBwb3MgPSBidWZmZXI7CiAgICBpbnQgY291bnQgPSAwOwoKICAgIGZvciAoOyBsZW47IHN0cisrLCBsZW4tLSkKICAgIHsKICAgICAgICBpZiAocG9zID4gYnVmZmVyICsgc2l6ZW9mKGJ1ZmZlcikgLSA4KQogICAgICAgIHsKICAgICAgICAgICAgZndyaXRlKCBidWZmZXIsIHBvcyAtIGJ1ZmZlciwgMSwgZiApOwogICAgICAgICAgICBjb3VudCArPSBwb3MgLSBidWZmZXI7CiAgICAgICAgICAgIHBvcyA9IGJ1ZmZlcjsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPiAxMjcpICAvKiBoZXggZXNjYXBlICovCiAgICAgICAgewogICAgICAgICAgICBpZiAobGVuID4gMSAmJiBzdHJbMV0gPCAxMjggJiYgaXN4ZGlnaXQoKGNoYXIpc3RyWzFdKSkKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHglMDR4IiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFx4JXgiLCAqc3RyICk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA8IDMyKSAgLyogb2N0YWwgb3IgQyBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmICghKnN0ciAmJiBsZW4gPT0gMSkgY29udGludWU7ICAvKiBkbyBub3Qgb3V0cHV0IHRlcm1pbmF0aW5nIE5VTEwgKi8KICAgICAgICAgICAgaWYgKGVzY2FwZXNbKnN0cl0gIT0gJy4nKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxcJWMiLCBlc2NhcGVzWypzdHJdICk7CiAgICAgICAgICAgIGVsc2UgaWYgKGxlbiA+IDEgJiYgc3RyWzFdID49ICcwJyAmJiBzdHJbMV0gPD0gJzcnKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxcJTAzbyIsICpzdHIgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxcJW8iLCAqc3RyICk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA9PSAnXFwnIHx8ICpzdHIgPT0gZXNjYXBlWzBdIHx8ICpzdHIgPT0gZXNjYXBlWzFdKSAqcG9zKysgPSAnXFwnOwogICAgICAgICpwb3MrKyA9ICpzdHI7CiAgICB9CiAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICBjb3VudCArPSBwb3MgLSBidWZmZXI7CiAgICByZXR1cm4gY291bnQ7Cn0KCi8qIGNvbnZlcnQgYW5zaSBzdHJpbmcgdG8gdW5pY29kZSBhbmQgZHVtcCB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyQXRvVyhMUENTVFIgc3RyQSxzaXplX3QgbGVuLEZJTEUgKmYsY2hhciBlc2NhcGVbMl0pCnsKICAgIFdDSEFSICpzdHJXOwogICAgaW50IHJldDsKCiAgICBpZiAoc3RyQSA9PSBOVUxMKSByZXR1cm4gMDsKICAgIHN0clcgPSBfc3RyZHVwbkF0b1coc3RyQSxsZW4pOwogICAgcmV0ID0gX2R1bXBfc3RyVyhzdHJXLGxlbixmLGVzY2FwZSk7CiAgICBmcmVlKHN0clcpOwogICAgcmV0dXJuIHJldDsKfQoKLyogYSBrZXkgdmFsdWUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0cnVjdCBrZXlfdmFsdWUgewogICAgV0NIQVIgICAgICAgICAgICAqbmFtZVc7ICAgLyogdmFsdWUgbmFtZSAqLwogICAgaW50ICAgICAgICAgICAgICAgdHlwZTsgICAgLyogdmFsdWUgdHlwZSAqLwogICAgc2l6ZV90ICAgICAgICAgICAgbGVuOyAgICAgLyogdmFsdWUgZGF0YSBsZW5ndGggaW4gYnl0ZXMgKi8KICAgIHZvaWQgICAgICAgICAgICAgKmRhdGE7ICAgIC8qIHBvaW50ZXIgdG8gdmFsdWUgZGF0YSAqLwp9OwoKLyogZHVtcCBhIHZhbHVlIHRvIGEgdGV4dCBmaWxlICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvcmVnaXN0cnkuYyAqLwpzdGF0aWMgdm9pZCBfZHVtcF92YWx1ZShzdHJ1Y3Qga2V5X3ZhbHVlICp2YWx1ZSxGSUxFICpmKQp7CiAgICBpbnQgaSwgY291bnQ7CgogICAgaWYgKHZhbHVlLT5uYW1lV1swXSkgewogICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgY291bnQgPSAxICsgX2R1bXBfc3RyVyh2YWx1ZS0+bmFtZVcsc3RybGVuVyh2YWx1ZS0+bmFtZVcpLGYsIlwiXCIiKTsKICAgICAgICBjb3VudCArPSBmcHJpbnRmKCBmLCAiXCI9IiApOwogICAgfQogICAgZWxzZSBjb3VudCA9IGZwcmludGYoIGYsICJAPSIgKTsKCiAgICBzd2l0Y2godmFsdWUtPnR5cGUpIHsKICAgICAgICBjYXNlIFJFR19TWjoKICAgICAgICBjYXNlIFJFR19FWFBBTkRfU1o6CiAgICAgICAgY2FzZSBSRUdfTVVMVElfU1o6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+dHlwZSAhPSBSRUdfU1opIGZwcmludGYoIGYsICJzdHIoJWQpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGlmICh2YWx1ZS0+ZGF0YSkgX2R1bXBfc3RyVyh2YWx1ZS0+ZGF0YSx2YWx1ZS0+bGVuL3NpemVvZihXQ0hBUiksZiwiXCJcIiIpOwogICAgICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICAgICAgaWYgKHZhbHVlLT5sZW4gPT0gc2l6ZW9mKERXT1JEKSkgewogICAgICAgICAgICAgICAgRFdPUkQgZHc7CiAgICAgICAgICAgICAgICBtZW1jcHkoICZkdywgdmFsdWUtPmRhdGEsIHNpemVvZihEV09SRCkgKTsKICAgICAgICAgICAgICAgIGZwcmludGYoIGYsICJkd29yZDolMDhseCIsIGR3ICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBlbHNlIGZhbGwgdGhyb3VnaCAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+dHlwZSA9PSBSRUdfQklOQVJZKSBjb3VudCArPSBmcHJpbnRmKCBmLCAiaGV4OiIgKTsKICAgICAgICAgICAgZWxzZSBjb3VudCArPSBmcHJpbnRmKCBmLCAiaGV4KCV4KToiLCB2YWx1ZS0+dHlwZSApOwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUtPmxlbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBjb3VudCArPSBmcHJpbnRmKCBmLCAiJTAyeCIsICooKHVuc2lnbmVkIGNoYXIgKil2YWx1ZS0+ZGF0YSArIGkpICk7CiAgICAgICAgICAgICAgICBpZiAoaSA8IHZhbHVlLT5sZW4tMSkgewogICAgICAgICAgICAgICAgICAgIGZwdXRjKCAnLCcsIGYgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoKytjb3VudCA+IDc2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoIGYsICJcXFxuICAiICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBmcHV0YyggJ1xuJywgZiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwovKgogICAgcmVnaGFjayAtIHdpbmRvd3MgMy4xMSByZWdpc3RyeSBkYXRhIGZvcm1hdCBkZW1vIHByb2dyYW0uCgogICAgVGhlIHJlZy5kYXQgZmlsZSBoYXMgMyBwYXJ0cywgYSBoZWFkZXIsIGEgdGFibGUgb2YgOC1ieXRlIGVudHJpZXMgdGhhdCBpcwogICAgYSBjb21iaW5lZCBoYXNoIHRhYmxlIGFuZCB0cmVlIGRlc2NyaXB0aW9uLCBhbmQgZmluYWxseSBhIHRleHQgdGFibGUuCgogICAgVGhlIGhlYWRlciBpcyBvYnZpb3VzIGZyb20gdGhlIHN0cnVjdCBoZWFkZXIuIFRoZSB0YWJvZmYxIGFuZCB0YWJvZmYyCiAgICBmaWVsZHMgYXJlIGFsd2F5cyAweDIwLCBhbmQgdGhlaXIgdXNhZ2UgaXMgdW5rbm93bi4KCiAgICBUaGUgOC1ieXRlIGVudHJ5IHRhYmxlIGhhcyB2YXJpb3VzIGVudHJ5IHR5cGVzLgoKICAgIHRhYmVudFswXSBpcyBhIHJvb3QgaW5kZXguIFRoZSBzZWNvbmQgd29yZCBoYXMgdGhlIGluZGV4IG9mIHRoZSByb290IG9mCiAgICAgICAgICAgIHRoZSBkaXJlY3RvcnkuCiAgICB0YWJlbnRbMS4uaGFzaHNpemVdIGlzIGEgaGFzaCB0YWJsZS4gVGhlIGZpcnN0IHdvcmQgaW4gdGhlIGhhc2ggZW50cnkgaXMKICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBrZXkvdmFsdWUgdGhhdCBoYXMgdGhhdCBoYXNoLiBEYXRhIHdpdGggdGhlIHNhbWUKICAgICAgICAgICAgaGFzaCB2YWx1ZSBhcmUgb24gYSBjaXJjdWxhciBsaXN0LiBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlCiAgICAgICAgICAgIGhhc2ggZW50cnkgYXJlIGFsd2F5cyB6ZXJvLgogICAgdGFiZW50W2hhc2hzaXplLi50YWJjbnRdIGlzIHRoZSB0cmVlIHN0cnVjdHVyZS4gVGhlcmUgYXJlIHR3byBraW5kcyBvZgogICAgICAgICAgICBlbnRyeTogZGlyZW50IGFuZCBrZXllbnQvdmFsZW50LiBUaGV5IGFyZSBpZGVudGlmaWVkIGJ5IGNvbnRleHQuCiAgICB0YWJlbnRbZnJlZWlkeF0gaXMgdGhlIGZpcnN0IGZyZWUgZW50cnkuIFRoZSBmaXJzdCB3b3JkIGluIGEgZnJlZSBlbnRyeQogICAgICAgICAgICBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgZnJlZSBlbnRyeS4gVGhlIGxhc3QgaGFzIDAgYXMgYSBsaW5rLgogICAgICAgICAgICBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlIGZyZWUgbGlzdCBhcmUgcHJvYmFibHkgaXJyZWxldmFudC4KCiAgICBFbnRyaWVzIGluIHRleHQgdGFibGUgYXJlIHByZWNlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKICAgIGNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwogICAgdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwogICAgdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewogICAgdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewogICAgdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewogICAgdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICBbSW50ZXJuYWxdICovCnZvaWQgX3czMV9kdW1wdHJlZSh1bnNpZ25lZCBzaG9ydCBpZHgsdW5zaWduZWQgY2hhciAqdHh0LHN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLHN0cnVjdCBfdzMxX2hlYWRlciAqaGVhZCxIS0VZIGhrZXksdGltZV90IGxhc3Rtb2RpZmllZCwgaW50IGxldmVsKQp7CiAgICBzdHJ1Y3QgX3czMV9kaXJlbnQgKmRpcjsKICAgIHN0cnVjdCBfdzMxX2tleWVudCAqa2V5OwogICAgc3RydWN0IF93MzFfdmFsZW50ICp2YWw7CiAgICBIS0VZIHN1YmtleSA9IDA7CiAgICBzdGF0aWMgY2hhcgl0YWlsWzQwMF07CgogICAgd2hpbGUgKGlkeCE9MCkgewogICAgICAgIGRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgogICAgICAgIGlmIChkaXItPmtleV9pZHgpIHsKICAgICAgICAgICAga2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKICAgICAgICAgICAgbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKICAgICAgICAgICAgdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKICAgICAgICAgICAgLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZQogICAgICAgICAgICAgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIWxldmVsICYmICFzdHJjbXAodGFpbCwiLmNsYXNzZXMiKSkgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgICAgICAgICAgaWYgKFJlZ0NyZWF0ZUtleUEoIGhrZXksIHRhaWwsICZzdWJrZXkgKSAhPSBFUlJPUl9TVUNDRVNTKSBzdWJrZXkgPSAwOwogICAgICAgICAgICAvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewogICAgICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwogICAgICAgICAgICAgICAgICAgIG1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZUEoIHN1YmtleSwgTlVMTCwgUkVHX1NaLCB0YWlsLCAwICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgVFJBQ0UoInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CiAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsc3Via2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgIH0KICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpCnsKICAgIEhGSUxFIGhmOwogICAgc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CiAgICBzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKICAgIHVuc2lnbmVkIGNoYXIJCSp0eHQ7CiAgICB1bnNpZ25lZCBpbnQJCWxlbjsKICAgIE9GU1RSVUNUCQlvZnM7CiAgICBCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87CiAgICB0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgaGYgPSBPcGVuRmlsZSgicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKICAgIGlmIChoZj09SEZJTEVfRVJST1IpIHJldHVybjsKCiAgICAvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KICAgIGlmIChzaXplb2YoaGVhZCkhPV9scmVhZChoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CiAgICAvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCiAgICB0YWIgPSBfeG1hbGxvYyhsZW4pOwogICAgaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOwogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogcmVhZCB0ZXh0ICovCiAgICB0eHQgPSBfeG1hbGxvYyhoZWFkLnRleHRzaXplKTsKICAgIGlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOwogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZChoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKICAgICAgICBFUlIoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOwogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKICAgICAgICBFUlIoIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKICAgIF93MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsSEtFWV9DTEFTU0VTX1JPT1QsbGFzdG1vZGlmaWVkLDApOwogICAgZnJlZSh0YWIpOwogICAgZnJlZSh0eHQpOwogICAgX2xjbG9zZShoZik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogIkNSRUciID0gVzk1X1JFR19DUkVHX0lEICovCiAgICBEV09SRAl2ZXJzaW9uOwkvKiA/Pz8/IDB4MDAwMTAwMDAgKi8KICAgIERXT1JECXJnZGJfb2ZmOwkvKiAweDA4IE9mZnNldCBvZiAxc3QgUkdEQi1ibG9jayAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwYyAqLwogICAgV09SRAlyZ2RiX251bTsJLyogMHgxMCAjIG9mIFJHREItYmxvY2tzICovCiAgICBXT1JECXVrMzsKICAgIERXT1JECXVrWzNdOwogICAgLyogcmdrbiAqLwp9IF93OTVjcmVnOwoKLyogU0VDVElPTiAyOiBEaXJlY3RvcnkgaW5mb3JtYXRpb24gKHRyZWUgc3RydWN0dXJlKQogKgogKiBvbmNlIG9uIG9mZnNldCAweDIwCiAqCiAqIHN0cnVjdHVyZTogW3Jna25dW2RrZV0qCShyZXBlYXQgdGlsbCBsYXN0X2RrZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KICAgIERXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KICAgIERXT1JEICAgbGFzdF9ka2U7ICAgICAgIC8qIE9mZnNldCB0byBsYXN0IERLRSA/ICovCiAgICBEV09SRAl1a1s0XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBTVFIga2V5X25hbWUsX3c5NWNyZWcgKmNyZWcsX3c5NXJna24gKnJna24sX3c5NWRrZSAqZGtlLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICBfdzk1ZGtoICogZGtoOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICAvKiBzcGVjaWFsIHJvb3Qga2V5ICovCiAgICBpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KICAgIHsKICAgICAgICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSAqLwogICAgICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgcmV0dXJuIF93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsKTsKICAgICAgICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNlYXJjaCBzdWJibG9jayAqLwogICAgaWYgKCEoZGtoID0gX3c5NV9sb29rdXBfZGtoKGNyZWcsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkpIHsKICAgICAgICBFUlIoImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkrZGtoLT5rZXluYW1lbGVuKzEpOwogICAgICAgIGlmIChzdHJjbXAobmV3X2tleV9uYW1lLCIiKSAhPSAwKSBzdHJjYXQobmV3X2tleV9uYW1lLCJcXCIpOwogICAgICAgIHN0cm5jYXQobmV3X2tleV9uYW1lLGRraC0+bmFtZSxka2gtPmtleW5hbWVsZW4pOwoKICAgICAgICAvKiB3YWxrIHNpYmxpbmcga2V5cyAqLwogICAgICAgIGlmIChka2UtPm5leHQgIT0gMHhmZmZmZmZmZiApIHsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dCksZixsZXZlbCkpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOgogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKGRraC0+dmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGt2KGRraCwgZGtlLT5uckxTLCBka2UtPm5yTVMsZikpIHsKICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgoZGtlLT5uZXh0c3ViID09IDB4ZmZmZmZmZmYpICYmIChka2gtPnZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkpOwoKICAgIC8qIG5leHQgc3ViIGtleSAqLwogICAgaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSB7CiAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKG5ld19rZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLGYsbGV2ZWwtMSkpIHsKICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KLyogZW5kIHdpbmRvd3MgOTUgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93cyBOVCByZWdpc3RyeSBsb2FkZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogTlQgUkVHSVNUUlkgTE9BREVSICovCgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaWZuZGVmIE1BUF9GQUlMRUQKI2RlZmluZSBNQVBfRkFJTEVEICgoTFBWT0lEKS0xKQojZW5kaWYKCiNkZWZpbmUgTlRfUkVHX0JMT0NLX1NJWkUgICAgICAgICAgICAweDEwMDAKCiNkZWZpbmUgTlRfUkVHX0hFQURFUl9CTE9DS19JRCAgICAgICAweDY2Njc2NTcyCS8qIHJlZ2YgKi8KI2RlZmluZSBOVF9SRUdfUE9PTF9CTE9DS19JRCAgICAgICAgIDB4NkU2OTYyNjgJLyogaGJpbiAqLwojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfSUQgICAgICAgICAgMHg2YjZlIC8qIG5rICovCiNkZWZpbmUgTlRfUkVHX1ZBTFVFX0JMT0NLX0lEICAgICAgICAweDZiNzYgLyogdmsgKi8KCi8qIHN1YmJsb2NrcyBvZiBuayAqLwojZGVmaW5lIE5UX1JFR19IQVNIX0JMT0NLX0lEICAgICAgICAgMHg2NjZjIC8qIGxmICovCiNkZWZpbmUgTlRfUkVHX05PSEFTSF9CTE9DS19JRCAgICAgICAweDY5NmMgLyogbGkgKi8KI2RlZmluZSBOVF9SRUdfUklfQkxPQ0tfSUQJICAgICAweDY5NzIgLyogcmkgKi8KCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19UWVBFICAgICAgICAweDIwCiNkZWZpbmUgTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUgICAweDJjCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NjY2NzY1NzIgJ3JlZ2YnKi8KICAgIERXT1JECXVrMTsJCS8qIDB4MDQgKi8KICAgIERXT1JECXVrMjsJCS8qIDB4MDggKi8KICAgIEZJTEVUSU1FCURhdGVNb2RpZmllZDsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJdWs1OwkJLyogMHgxYyAqLwogICAgRFdPUkQJdWs2OwkJLyogMHgyMCAqLwogICAgRFdPUkQJUm9vdEtleUJsb2NrOwkvKiAweDI0ICovCiAgICBEV09SRAlCbG9ja1NpemU7CS8qIDB4MjggKi8KICAgIERXT1JEICAgdWs3WzExNl07CiAgICBEV09SRAlDaGVja3N1bTsgLyogYXQgb2Zmc2V0IDB4MUZDICovCn0gbnRfcmVnZjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWJsb2Nrc2l6ZTsKICAgIEJZVEUJZGF0YVsxXTsKfSBudF9oYmluX3N1YjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2RTY5NjI2OCAnaGJpbicgKi8KICAgIERXT1JECW9mZl9wcmV2OwogICAgRFdPUkQJb2ZmX25leHQ7CiAgICBEV09SRAl1azE7CiAgICBEV09SRAl1azI7CQkvKiAweDEwICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAlzaXplOwkJLyogMHgxQyAqLwogICAgbnRfaGJpbl9zdWIJaGJpbl9zdWI7CS8qIDB4MjAgKi8KfSBudF9oYmluOwoKLyoKICogdGhlIHZhbHVlX2xpc3QgY29uc2lzdHMgb2Ygb2Zmc2V0cyB0byB0aGUgdmFsdWVzICh2aykKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJU3ViQmxvY2tJZDsJCS8qIDB4MDAgMHg2QjZFICovCiAgICBXT1JECVR5cGU7CQkJLyogMHgwMiBmb3IgdGhlIHJvb3Qta2V5OiAweDJDLCBvdGhlcndpc2UgMHgyMCovCiAgICBGSUxFVElNRQl3cml0ZXRpbWU7CS8qIDB4MDQgKi8KICAgIERXT1JECXVrMTsJCQkvKiAweDBDICovCiAgICBEV09SRAlwYXJlbnRfb2ZmOwkJLyogMHgxMCBPZmZzZXQgb2YgT3duZXIvUGFyZW50IGtleSAqLwogICAgRFdPUkQJbnJfc3Via2V5czsJCS8qIDB4MTQgbnVtYmVyIG9mIHN1Yi1LZXlzICovCiAgICBEV09SRAl1azg7CQkJLyogMHgxOCAqLwogICAgRFdPUkQJbGZfb2ZmOwkJCS8qIDB4MUMgT2Zmc2V0IG9mIHRoZSBzdWIta2V5IGxmLVJlY29yZHMgKi8KICAgIERXT1JECXVrMjsJCQkvKiAweDIwICovCiAgICBEV09SRAlucl92YWx1ZXM7CQkvKiAweDI0IG51bWJlciBvZiB2YWx1ZXMgKi8KICAgIERXT1JECXZhbHVlbGlzdF9vZmY7CQkvKiAweDI4IE9mZnNldCBvZiB0aGUgVmFsdWUtTGlzdCAqLwogICAgRFdPUkQJb2ZmX3NrOwkJCS8qIDB4MmMgT2Zmc2V0IG9mIHRoZSBzay1SZWNvcmQgKi8KICAgIERXT1JECW9mZl9jbGFzczsJCS8qIDB4MzAgT2Zmc2V0IG9mIHRoZSBDbGFzcy1OYW1lICovCiAgICBEV09SRAl1azM7CQkJLyogMHgzNCAqLwogICAgRFdPUkQJdWs0OwkJCS8qIDB4MzggKi8KICAgIERXT1JECXVrNTsJCQkvKiAweDNjICovCiAgICBEV09SRAl1azY7CQkJLyogMHg0MCAqLwogICAgRFdPUkQJdWs3OwkJCS8qIDB4NDQgKi8KICAgIFdPUkQJbmFtZV9sZW47CQkvKiAweDQ4IG5hbWUtbGVuZ3RoICovCiAgICBXT1JECWNsYXNzX2xlbjsJCS8qIDB4NGEgY2xhc3MtbmFtZSBsZW5ndGggKi8KICAgIGNoYXIJbmFtZVsxXTsJCS8qIDB4NGMga2V5LW5hbWUgKi8KfSBudF9uazsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECW9mZl9uazsJLyogMHgwMCAqLwogICAgRFdPUkQJbmFtZTsJLyogMHgwNCAqLwp9IGhhc2hfcmVjOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2NjZjICovCiAgICBXT1JECW5yX2tleXM7CS8qIDB4MDYgKi8KICAgIGhhc2hfcmVjCWhhc2hfcmVjWzFdOwp9IG50X2xmOwoKLyoKIGxpc3Qgb2Ygc3Via2V5cyB3aXRob3V0IGhhc2gKCiBsaSAtLSstLT5uawogICAgICB8CiAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTZjICovCiAgICBXT1JECW5yX2tleXM7CiAgICBEV09SRAlvZmZfbmtbMV07Cn0gbnRfbGk7CgovKgogdGhpcyBpcyBhIGludGVybWVkaWF0ZSBub2RlCgogcmkgLS0rLS0+bGktLSstLT5uawogICAgICB8ICAgICAgICsKICAgICAgfCAgICAgICArLS0+bmsKICAgICAgfAogICAgICArLS0+bGktLSstLT5uawogICAgICAgICAgICAgICsKCSAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTcyICovCiAgICBXT1JECW5yX2xpOwkJLyogMHgwMiBudW1iZXIgb2ZmIG9mZnNldHMgKi8KICAgIERXT1JECW9mZl9saVsxXTsJLyogMHgwNCBwb2ludHMgdG8gbGkgKi8KfSBudF9yaTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwICd2aycgKi8KICAgIFdPUkQJbmFtX2xlbjsKICAgIERXT1JECWRhdGFfbGVuOwogICAgRFdPUkQJZGF0YV9vZmY7CiAgICBEV09SRAl0eXBlOwogICAgV09SRAlmbGFnOwogICAgV09SRAl1azE7CiAgICBjaGFyCW5hbWVbMV07Cn0gbnRfdms7CgovKgogKiBnZXRzIGEgdmFsdWUKICoKICogdmstPmZsYWc6CiAqICAwIHZhbHVlIGlzIGEgZGVmYXVsdCB2YWx1ZQogKiAgMSB0aGUgdmFsdWUgaGFzIGEgbmFtZQogKgogKiB2ay0+ZGF0YV9sZW4KICogIGxlbiBvZiB0aGUgd2hvbGUgZGF0YSBibG9jawogKiAgLSByZWdfc3ogKHVuaWNvZGUpCiAqICAgIGJ5dGVzIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgXDAgPSAyKihudW1iZXJfb2ZfY2hhcnMrMSkKICogIC0gcmVnX2R3b3JkLCByZWdfYmluYXJ5OgogKiAgICBpZiBoaWdoZXN0IGJpdCBvZiBkYXRhX2xlbiBpcyBzZXQgZGF0YV9vZmYgY29udGFpbnMgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX3ZrKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBudF92ayAqdmssRklMRSAqZikKewogICAgQllURSAqcGRhdGEgPSAoQllURSAqKShiYXNlK3ZrLT5kYXRhX29mZis0KTsgLyogc3RhcnQgb2YgZGF0YSAqLwogICAgc3RydWN0IGtleV92YWx1ZSB2YWx1ZTsKCiAgICBpZiAodmstPmlkICE9IE5UX1JFR19WQUxVRV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBibG9jayBmb3VuZCAoMHglMDR4KSwgcGxlYXNlIHJlcG9ydCFcbiIsIHZrLT5pZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHZhbHVlLm5hbWVXID0gX3N0cmR1cG5BdG9XKHZrLT5uYW1lLHZrLT5uYW1fbGVuKTsKICAgIHZhbHVlLnR5cGUgPSB2ay0+dHlwZTsKICAgIHZhbHVlLmxlbiA9ICh2ay0+ZGF0YV9sZW4gJiAweDdmZmZmZmZmKTsKICAgIHZhbHVlLmRhdGEgPSAodmstPmRhdGFfbGVuICYgMHg4MDAwMDAwMCkgPyAoTFBCWVRFKSYodmstPmRhdGFfb2ZmKTogcGRhdGE7CgogICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgZnJlZSh2YWx1ZS5uYW1lVyk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGl0J3MgY2FsbGVkIGZyb20gX250X2R1bXBfbGYoKSAqLwpzdGF0aWMgaW50IF9udF9kdW1wX25rKExQU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKTsKCi8qCiAqIGdldCB0aGUgc3Via2V5cwogKgogKiB0aGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgaGFzaCBvZiBhIGtleW5hbWUgYW5kIHBvaW50cyB0byBhbGwKICogc3Via2V5cwogKgogKiBleGNlcHRpb246IGlmIHRoZSBpZCBpcyAnaWwnIHRoZXJlIGFyZSBubyBoYXNoIHZhbHVlcyBhbmQgZXZlcnkKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X2R1bXBfbGYoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqbGYsIEZJTEUgKmYsIGludCBsZXZlbCkKewogICAgaW50IGk7CgogICAgaWYgKGxmLT5pZCA9PSBOVF9SRUdfSEFTSF9CTE9DS19JRCkgewogICAgICAgIGlmIChzdWJrZXlzICE9IGxmLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGYtPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsZi0+aGFzaF9yZWNbaV0ub2ZmX25rKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSB7CiAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopbGY7CiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGktPm5yX2tleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICBmb3IgKGk9MDsgaTxsaS0+bnJfa2V5czsgaSsrKQogICAgICAgICAgICBpZiAoIV9udF9kdW1wX25rKGtleV9uYW1lLCBiYXNlLCAobnRfbmsqKShiYXNlK2xpLT5vZmZfbmtbaV0rNCksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgIH0gZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19SSV9CTE9DS19JRCkgeyAgLyogcmkgKi8KICAgICAgICBudF9yaSAqIHJpID0gKG50X3JpKilsZjsKICAgICAgICBpbnQgbGlfc3Via2V5cyA9IDA7CgogICAgICAgIC8qIGNvdW50IGFsbCBzdWJrZXlzICovCiAgICAgICAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspIHsKICAgICAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYobGktPmlkICE9IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIGdvdG8gZXJyb3IyOwogICAgICAgICAgICBsaV9zdWJrZXlzICs9IGxpLT5ucl9rZXlzOwogICAgICAgIH0KCiAgICAgICAgLyogY2hlY2sgbnVtYmVyICovCiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGlfc3Via2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUga2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICpsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihrZXlfbmFtZSwgYmFzZSwgbGktPm5yX2tleXMsIChudF9sZiopbGksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgICAgICB9CiAgICB9IGVsc2UgZ290byBlcnJvcjI7CgogICAgcmV0dXJuIFRSVUU7CgplcnJvcjI6CiAgICBpZiAobGYtPmlkID09IDB4Njg2YykKICAgICAgICBGSVhNRSgidW5rbm93biBXaW4gWFAgbm9kZSBpZCAweDY4NmM6IGRvIHdlIG5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGl0ID9cbiIpOwogICAgZWxzZQogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIGxmLT5pZCk7CiAgICByZXR1cm4gVFJVRTsKCmVycm9yMToKICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISAoaW5jb25zaXN0ZW50IG51bWJlciBvZiBzdWJrZXlzKVxuIik7CiAgICByZXR1cm4gRkFMU0U7CgplcnJvcjoKICAgIEVSUigiZXJyb3IgcmVhZGluZyBsZiBibG9ja1xuIik7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qIF9udF9kdW1wX25rIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCkKewogICAgdW5zaWduZWQgaW50IG47CiAgICBEV09SRCAqdmw7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKICAgIFRSQUNFKCIlc1xuIiwga2V5X25hbWUpOwoKICAgIGlmIChuay0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbmstPlN1YkJsb2NrSWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKG5rLT5UeXBlIT1OVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgJiYgKCgobnRfbmsqKShiYXNlK25rLT5wYXJlbnRfb2ZmKzQpKS0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSkgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0IVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIGNyZWF0ZSB0aGUgbmV3IGtleSAqLwogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkrbmstPm5hbWVfbGVuKzEpOwogICAgICAgIGlmIChzdHJjbXAobmV3X2tleV9uYW1lLCIiKSAhPSAwKSBzdHJjYXQobmV3X2tleV9uYW1lLCJcXCIpOwogICAgICAgIHN0cm5jYXQobmV3X2tleV9uYW1lLG5rLT5uYW1lLG5rLT5uYW1lX2xlbik7CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjoKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChuay0+bnJfdmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKChuay0+bnJfc3Via2V5cyA9PSAwKSAmJiAobmstPm5yX3ZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CgogICAgICAgIC8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCiAgICAgICAgdmwgPSAoRFdPUkQgKikoYmFzZStuay0+dmFsdWVsaXN0X29mZis0KTsKICAgICAgICBmb3IgKG49MDsgbjxuay0+bnJfdmFsdWVzOyBuKyspIHsKICAgICAgICAgICAgbnRfdmsgKiB2ayA9IChudF92ayopKGJhc2Urdmxbbl0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfdmsobmV3X2tleV9uYW1lLCBiYXNlLCB2aywgZikpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfc3RyZHVwbkEoa2V5X25hbWUsc3RybGVuKGtleV9uYW1lKSk7CgogICAgLyogbG9vcCB0aHJvdWdoIHRoZSBzdWJrZXlzICovCiAgICBpZiAobmstPm5yX3N1YmtleXMpIHsKICAgICAgICBudF9sZiAqbGYgPSAobnRfbGYqKShiYXNlK25rLT5sZl9vZmYrNCk7CiAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihuZXdfa2V5X25hbWUsIGJhc2UsIG5rLT5ucl9zdWJrZXlzLCBsZiwgZiwgbGV2ZWwtMSkpIHsKICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9CgovKiBlbmQgbnQgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2V0X3JlZ2lzdHJ5X2xldmVscyBbSW50ZXJuYWxdCiAqCiAqIHNldCBsZXZlbCB0byAwIGZvciBsb2FkaW5nIHN5c3RlbSBmaWxlcwogKiBzZXQgbGV2ZWwgdG8gMSBmb3IgbG9hZGluZyB1c2VyIGZpbGVzCiAqLwpzdGF0aWMgdm9pZCBfc2V0X3JlZ2lzdHJ5X2xldmVscyhpbnQgbGV2ZWwsaW50IHNhdmluZyxpbnQgcGVyaW9kKQp7CiAgICBTRVJWRVJfU1RBUlRfUkVRKCBzZXRfcmVnaXN0cnlfbGV2ZWxzICkKICAgIHsKCXJlcS0+Y3VycmVudCA9IGxldmVsOwoJcmVxLT5zYXZpbmcgID0gc2F2aW5nOwogICAgICAgIHJlcS0+cGVyaW9kICA9IHBlcmlvZDsKICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwp9CgovKiBfc2F2ZV9hdF9leGl0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX3NhdmVfYXRfZXhpdChIS0VZIGhrZXksTFBDU1RSIHBhdGgpCnsKICAgIExQQ1NUUiBjb25mZGlyID0gd2luZV9nZXRfY29uZmlnX2RpcigpOwoKICAgIFNFUlZFUl9TVEFSVF9SRVEoIHNhdmVfcmVnaXN0cnlfYXRleGl0ICkKICAgIHsKICAgICAgICByZXEtPmhrZXkgPSBoa2V5OwogICAgICAgIHdpbmVfc2VydmVyX2FkZF9kYXRhKCByZXEsIGNvbmZkaXIsIHN0cmxlbihjb25mZGlyKSApOwogICAgICAgIHdpbmVfc2VydmVyX2FkZF9kYXRhKCByZXEsIHBhdGgsIHN0cmxlbihwYXRoKSsxICk7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyogY29uZmlndXJlIHNhdmUgZmlsZXMgYW5kIHN0YXJ0IHRoZSBwZXJpb2RpYyBzYXZpbmcgdGltZXIgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfaW5pdF9yZWdpc3RyeV9zYXZpbmcoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IGFsbDsKICAgIGludCBwZXJpb2QgPSAwOwogICAgY2hhciBidWZmZXJbMjBdOwoKICAgIGFsbCA9ICFQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJyZWdpc3RyeSIsIlNhdmVPbmx5VXBkYXRlZEtleXMiLDEpOwogICAgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAicmVnaXN0cnkiLCAiUGVyaW9kaWNTYXZlIiwgIiIsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikgKTsKICAgIGlmIChidWZmZXJbMF0pIHBlcmlvZCA9IGF0b2koYnVmZmVyKTsKCiAgICAvKiBzZXQgc2F2aW5nIGxldmVsICgwIGZvciBzYXZpbmcgZXZlcnl0aGluZywgMSBmb3Igc2F2aW5nIG9ubHkgbW9kaWZpZWQga2V5cykgKi8KICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDEsIWFsbCxwZXJpb2QqMTAwMCk7CgogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiV3JpdGV0b0hvbWVSZWdpc3RyeUZpbGVzIiwxKSkKICAgIHsKICAgICAgICBfc2F2ZV9hdF9leGl0KEhLRVlfQ1VSUkVOVF9VU0VSLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KEhLRVlfTE9DQUxfTUFDSElORSwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICAgICAgX3NhdmVfYXRfZXhpdChoa2V5X3VzZXJzX2RlZmF1bHQsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICB9Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLgogKi8Kc3RhdGljIHZvaWQgX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyh2b2lkKSB7CglIS0VZCWhrZXk7CgljaGFyCWJ1ZlsyMDBdOwoKCVRSQUNFKCIodm9pZClcbiIpOwoKCVJlZ0NyZWF0ZUtleUEoSEtFWV9EWU5fREFUQSwiUGVyZlN0YXRzXFxTdGF0RGF0YSIsJmhrZXkpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgogICAgICAgIC8qIFRoaXMgd2FzIGFuIE9wZW4sIGJ1dCBzaW5jZSBpdCBpcyBjYWxsZWQgYmVmb3JlIHRoZSByZWFsIHJlZ2lzdHJpZXMKICAgICAgICAgICBhcmUgbG9hZGVkLCBpdCB3YXMgY2hhbmdlZCB0byBhIENyZWF0ZSAtIE1UQiA5ODA1MDcqLwoJUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4QShoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiU3lzdGVtVHlwZSBXSU5FIixzdHJsZW4oIlN5c3RlbVR5cGUgV0lORSIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93cyBOVFxcQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudEJ1aWxkTnVtYmVyCgkgKgkJCQkJCUN1cnJlbnRUeXBlCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPd25lcgoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3JnYW5pemF0aW9uCgkgKgoJICovCgkvKiBTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxTZXJ2aWNlc1xcU05NUFxcUGFyYW1ldGVyc1xcUkZDMTE1NkFnZW50CgkgKiAJCQkJCXN0cmluZwlTeXNDb250YWN0CgkgKiAJCQkJCXN0cmluZwlTeXNMb2NhdGlvbgoJICogCQkJCQkJU3lzU2VydmljZXMKCSAqLwoJaWYgKC0xIT1nZXRob3N0bmFtZShidWYsMjAwKSkgewoJCVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJmhrZXkpOwoJCVJlZ1NldFZhbHVlRXhBKGhrZXksIkNvbXB1dGVyTmFtZSIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKzEpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQoKICAgICAgICBSZWdDcmVhdGVLZXlBKEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7Cn0KCiNkZWZpbmUgUkVHX0RPTlRMT0FEIC0xCiNkZWZpbmUgUkVHX1dJTjMxICAgICAwCiNkZWZpbmUgUkVHX1dJTjk1ICAgICAxCiNkZWZpbmUgUkVHX1dJTk5UICAgICAyCgovKiByZXR1cm4gdGhlIHR5cGUgb2YgbmF0aXZlIHJlZ2lzdHJ5IFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZ2V0X3JlZ190eXBlKHZvaWQpCnsKICAgIGNoYXIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogICAgY2hhciB0bXBbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBpbnQgcmV0ID0gUkVHX1dJTjMxOwoKICAgIEdldFdpbmRvd3NEaXJlY3RvcnlBKHdpbmRpcixNQVhfUEFUSE5BTUVfTEVOKTsKCiAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbTMyL2NvbmZpZy9zeXN0ZW0gLS0+IHdpbm50ICovCiAgICBzdHJjcHkodG1wLCB3aW5kaXIpOwogICAgc3RybmNhdCh0bXAsICJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4odG1wKSAtIDEpOwogICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNBKHRtcCkgIT0gKERXT1JEKS0xKSB7CiAgICAgIHJldCA9IFJFR19XSU5OVDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtLmRhdCAtLT4gd2luOTUgKi8KICAgICAgc3RyY3B5KHRtcCwgd2luZGlyKTsKICAgICAgc3RybmNhdCh0bXAsICJcXHN5c3RlbS5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHRtcCkgLSAxKTsKICAgICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNBKHRtcCkgIT0gKERXT1JEKS0xKSB7CiAgICAgICAgcmV0ID0gUkVHX1dJTjk1OwogICAgICB9CiAgICB9CgogICAgaWYgKChyZXQgPT0gUkVHX1dJTk5UKSAmJiAoIVBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCB0bXAsIE1BWF9QQVRITkFNRV9MRU4pKSkgewogICAgICAgTUVTU0FHRSgiV2hlbiB5b3UgYXJlIHJ1bm5pbmcgd2l0aCBhIG5hdGl2ZSBOVCBkaXJlY3Rvcnkgc3BlY2lmeVxuIik7CiAgICAgICBNRVNTQUdFKCInUHJvZmlsZT08cHJvZmlsZWRpcmVjdG9yeT4nIG9yIGRpc2FibGUgbG9hZGluZyBvZiBXaW5kb3dzXG4iKTsKICAgICAgIE1FU1NBR0UoInJlZ2lzdHJ5IChMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXM9TilcbiIpOwogICAgICAgcmV0ID0gUkVHX0RPTlRMT0FEOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCiNkZWZpbmUgV0lORV9SRUdfVkVSX0VSUk9SICAtMQojZGVmaW5lIFdJTkVfUkVHX1ZFUl8xICAgICAgIDAKI2RlZmluZSBXSU5FX1JFR19WRVJfMiAgICAgICAxCiNkZWZpbmUgV0lORV9SRUdfVkVSX09MRCAgICAgMgojZGVmaW5lIFdJTkVfUkVHX1ZFUl9VTktOT1dOIDMKCi8qIHJldHVybiB0aGUgdmVyc2lvbiBvZiB3aW5lIHJlZ2lzdHJ5IGZpbGUgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9nZXRfd2luZV9yZWdpc3RyeV9maWxlX2Zvcm1hdF92ZXJzaW9uKExQQ1NUUiBmbikKewogICAgRklMRSAqZjsKICAgIGNoYXIgdG1wWzUwXTsKICAgIGludCB2ZXI7CgogICAgaWYgKChmPWZvcGVuKGZuLCJydCIpKSA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSX0VSUk9SOwogICAgfQoKICAgIGlmIChmZ2V0cyh0bXAsNTAsZikgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIkVycm9yIHJlYWRpbmcgJXM6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgZmNsb3NlKGYpOwogICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfRVJST1I7CiAgICB9CiAgICBmY2xvc2UoZik7CgogICAgaWYgKHNzY2FuZih0bXAsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikgIT0gMSkgcmV0dXJuIFdJTkVfUkVHX1ZFUl9VTktOT1dOOwogICAgc3dpdGNoICh2ZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSXzI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfVU5LTk9XTjsKICAgIH0KfQoKLyogbG9hZCB0aGUgcmVnaXN0cnkgZmlsZSBpbiB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZIGhrZXksTFBDU1RSIGZuKQp7CiAgICBpbnQgZmlsZV9mb3JtYXQ7CgogICAgZmlsZV9mb3JtYXQgPSBfZ2V0X3dpbmVfcmVnaXN0cnlfZmlsZV9mb3JtYXRfdmVyc2lvbihmbik7CiAgICBzd2l0Y2ggKGZpbGVfZm9ybWF0KSB7CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSXzE6CiAgICAgICAgICAgIFdBUk4oIlVuYWJsZSB0byBsb2FkIHJlZ2lzdHJ5IGZpbGUgJXM6IG9sZCBmb3JtYXQgd2hpY2ggaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC5cbiIsZm4pOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfMjogewogICAgICAgICAgICBIQU5ETEUgZmlsZTsKICAgICAgICAgICAgaWYgKChmaWxlID0gRklMRV9DcmVhdGVGaWxlKCBmbiwgR0VORVJJQ19SRUFELCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9BVFRSSUJVVEVfTk9STUFMLCAwLCBUUlVFLCBEUklWRV9VTktOT1dOICkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTRVJWRVJfU1RBUlRfUkVRKCBsb2FkX3JlZ2lzdHJ5ICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICAgICAgICAgIHJlcS0+ZmlsZSAgICA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTRVJWRVJfRU5EX1JFUTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBmaWxlICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl9VTktOT1dOOgogICAgICAgICAgICBXQVJOKCJVbmFibGUgdG8gbG9hZCByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIGZvcm1hdC5cbiIsZm4pOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfRVJST1I6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgovKiBnZW5lcmF0ZSBhbmQgcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSB0bXAgZmlsZSBhbmQgYXNzb2NpYXRlZCBzdHJlYW0gW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2dldF90bXBfZm4oRklMRSAqKmYpCnsKICAgIExQU1RSIHJldDsKICAgIGludCB0bXBfZmQsY291bnQ7CgogICAgcmV0ID0gX3htYWxsb2MoNTApOwogICAgZm9yIChjb3VudCA9IDA7OykgewogICAgICAgIHNwcmludGYocmV0LCIvdG1wL3JlZyVseCUwNHgudG1wIiwobG9uZylnZXRwaWQoKSxjb3VudCsrKTsKICAgICAgICBpZiAoKHRtcF9mZCA9IG9wZW4ocmV0LE9fQ1JFQVQgfCBPX0VYQ0wgfCBPX1dST05MWSwwNjY2KSkgIT0gLTEpIGJyZWFrOwogICAgICAgIGlmIChlcnJubyAhPSBFRVhJU1QpIHsKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgICAgICpmID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgoKmYgPSBmZG9wZW4odG1wX2ZkLCJ3IikpID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgZmRvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBjbG9zZSh0bXBfZmQpOwogICAgICAgIGZyZWUocmV0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbjk1IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1NUUiBmbixpbnQgbGV2ZWwpCnsKICAgIGludCBmZDsKICAgIEZJTEUgKmY7CiAgICBET1NfRlVMTF9OQU1FIGZ1bGxfbmFtZTsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgc3RydWN0IHN0YXQgc3Q7CgogICAgX3c5NWNyZWcgKmNyZWc7CiAgICBfdzk1cmdrbiAqcmdrbjsKICAgIF93OTVka2UgKmRrZSwgKnJvb3RfZGtlOwoKICAgIGlmICghRE9TRlNfR2V0RnVsbE5hbWUoIGZuLCAwLCAmZnVsbF9uYW1lICkpIHJldHVybiBOVUxMOwoKICAgIC8qIG1hcCB0aGUgcmVnaXN0cnkgaW50byB0aGUgbWVtb3J5ICovCiAgICBpZiAoKGZkID0gb3BlbihmdWxsX25hbWUubG9uZ19uYW1lLCBPX1JET05MWSB8IE9fTk9OQkxPQ0spKSA9PSAtMSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoKGZzdGF0KGZkLCAmc3QpID09IC0xKSkgZ290byBlcnJvcjE7CiAgICBpZiAoIXN0LnN0X3NpemUpIGdvdG8gZXJyb3IxOwogICAgaWYgKChiYXNlID0gbW1hcChOVUxMLCBzdC5zdF9zaXplLCBQUk9UX1JFQUQsIE1BUF9QUklWQVRFLCBmZCwgMCkpID09IE1BUF9GQUlMRUQpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gVzk1X1JFR19DUkVHX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLGZuKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGNyZWcgPSBiYXNlOwogICAgLyogbG9hZCB0aGUgaGVhZGVyIChyZ2tuKSAqLwogICAgcmdrbiA9IChfdzk1cmdrbiopKGNyZWcgKyAxKTsKICAgIGlmIChyZ2tuLT5pZCAhPSBXOTVfUkVHX1JHS05fSUQpIHsKICAgICAgICBFUlIoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJWx4XG4iLCByZ2tuLT5pZCk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5yb290X29mZiAhPSAweDIwKSB7CiAgICAgICAgRVJSKCJyZ2tuLT5yb290X29mZiBub3QgMHgyMCwgcGxlYXNlIHJlcG9ydCAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPmxhc3RfZGtlID4gcmdrbi0+c2l6ZSkKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGxhc3RfZGtlID4gc2l6ZSFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgLyogdmVyaWZ5IGxhc3QgZGtlICovCiAgICBka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+bGFzdF9ka2UpOwogICAgaWYgKGRrZS0+eDEgIT0gMHg4MDAwMDAwMCkKICAgIHsgLyogd3JvbmcgbWFnaWMgKi8KICAgICAgRVJSKCJsYXN0IGRrZSBpbnZhbGlkICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnNpemUgPiBjcmVnLT5yZ2RiX29mZikKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJna24gc2l6ZSA+IHJnZGJfb2ZmICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgcm9vdF9ka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+cm9vdF9vZmYpOwogICAgaWYgKCAocm9vdF9ka2UtPnByZXZsdmwgIT0gMHhmZmZmZmZmZikgfHwgKHJvb3RfZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYpICkKICAgIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgaW52YWxpZCByb290IGRrZSAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF93OTVfZHVtcF9ka2UoIiIsY3JlZyxyZ2tuLHJvb3RfZGtlLGYsbGV2ZWwpOwogICAgZmNsb3NlKGYpOwoKZXJyb3I6CiAgICBpZihyZXQgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXMuXG4iLGZuKTsKICAgICAgICBFUlIoIlBsZWFzZSByZXBvcnQgdGhpcy5cbiIpOwogICAgICAgIEVSUigiTWFrZSBhIGJhY2t1cCBvZiB0aGUgZmlsZSwgcnVuIGEgZ29vZCByZWcgY2xlYW5lciBwcm9ncmFtIGFuZCB0cnkgYWdhaW4hXG4iKTsKICAgIH0KCiAgICBtdW5tYXAoYmFzZSwgc3Quc3Rfc2l6ZSk7CmVycm9yMToKICAgIGNsb3NlKGZkKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2lubnQgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDU1RSIGZuLGludCBsZXZlbCkKewogICAgRklMRSAqZjsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgSEFORExFIGhGaWxlOwogICAgSEFORExFIGhNYXBwaW5nOwoKICAgIG50X3JlZ2YgKnJlZ2Y7CiAgICBudF9oYmluICpoYmluOwogICAgbnRfaGJpbl9zdWIgKmhiaW5fc3ViOwogICAgbnRfbmsgKm5rOwoKICAgIFRSQUNFKCIlc1xuIiwgZm4pOwoKICAgIGhGaWxlID0gQ3JlYXRlRmlsZUEoIGZuLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwogICAgaE1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ0EoIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZfFNFQ19DT01NSVQsIDAsIDAsIE5VTEwgKTsKICAgIGlmICghaE1hcHBpbmcpIGdvdG8gZXJyb3IxOwogICAgYmFzZSA9IE1hcFZpZXdPZkZpbGUoIGhNYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggaE1hcHBpbmcgKTsKICAgIGlmICghYmFzZSkgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2lubnQgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLGZuKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIHN0YXJ0IGJsb2NrICovCiAgICByZWdmID0gYmFzZTsKCiAgICAvKiBoYmluIGJsb2NrICovCiAgICBoYmluID0gKG50X2hiaW4qKSgoY2hhciopIGJhc2UgKyAweDEwMDApOwogICAgaWYgKGhiaW4tPmlkICE9IE5UX1JFR19QT09MX0JMT0NLX0lEKSB7CiAgICAgIEVSUiggImhiaW4gYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkgewogICAgICBFUlIoICJoYmluX3N1YiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBuayBibG9jayAqLwogICAgbmsgPSAobnRfbmsqKSYoaGJpbl9zdWItPmRhdGFbMF0pOwogICAgaWYgKG5rLT5UeXBlICE9IE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSB7CiAgICAgIEVSUiggInNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfbnRfZHVtcF9uaygiIiwoY2hhciopYmFzZSsweDEwMDAsbmssZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIFVubWFwVmlld09mRmlsZSggYmFzZSApOwplcnJvcjE6CiAgICBDbG9zZUhhbmRsZShoRmlsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IG5hdGl2ZSByZWdpc3RyeSB0byB3aW5lIGZvcm1hdCBhbmQgbG9hZCBpdCB2aWEgc2VydmVyIGNhbGwgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoTFBDU1RSIGZuLEhLRVkgaGtleSxpbnQgcmVnX3R5cGUsaW50IGxldmVsKQp7CiAgICBMUFNUUiB0bXAgPSBOVUxMOwoKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDoKICAgICAgICAgICAgLyogRklYTUU6IGZvbGxvd2luZyBmdW5jdGlvbiBkb2Vzbid0IHJlYWxseSBjb252ZXJ0IHlldCAqLwogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICAgICAgICBFUlIoIkRvbid0IGtub3cgaG93IHRvIGNvbnZlcnQgbmF0aXZlIDMuMSByZWdpc3RyeSB5ZXQuXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmtub3duIHJlZ2lzdHJ5IGZvcm1hdCBwYXJhbWV0ZXIgKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmICh0bXAgIT0gTlVMTCkgewogICAgICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5LHRtcCk7CiAgICAgICAgVFJBQ0UoIkZpbGUgJXMgc3VjY2Vzc2Z1bGx5IGNvbnZlcnRlZCB0byAlcyBhbmQgbG9hZGVkIHRvIHJlZ2lzdHJ5LlxuIixmbix0bXApOwogICAgICAgIHVubGluayh0bXApOwogICAgfQogICAgZWxzZSBXQVJOKCJVbmFibGUgdG8gY29udmVydCAlcyAoZG9lc24ndCBleGlzdD8pXG4iLGZuKTsKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgbmF0aXZlIHdpbmRvd3MgcmVnaXN0cnkgZmlsZXMgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIGludCByZWdfdHlwZTsKICAgIGNoYXIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogICAgY2hhciBwYXRoW01BWF9QQVRITkFNRV9MRU5dOwoKICAgIEdldFdpbmRvd3NEaXJlY3RvcnlBKHdpbmRpcixNQVhfUEFUSE5BTUVfTEVOKTsKCiAgICByZWdfdHlwZSA9IF9nZXRfcmVnX3R5cGUoKTsKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDogewogICAgICAgICAgICBIS0VZIGhrZXk7CgogICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIG50dXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkgewogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcbnR1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxkZWZhdWx0Iik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAqIEZJWE1FCiAgICAgICAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNZU1RFTSIsICZoa2V5KSkgewoJICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKCSAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIpOwogICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU09GVFdBUkUiLCAmaGtleSkpIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzb2Z0d2FyZSIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2FtIik7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzZWN1cml0eSIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXENsb25lIiwmaGtleSkpIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoImM6XFxzeXN0ZW0uMXN0IixIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtLmRhdCIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcY2xhc3Nlcy5kYXQiKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DTEFTU0VTX1JPT1QsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygiV2luZSIsIlByb2ZpbGUiLCIiLHBhdGgsTUFYX1BBVEhOQU1FX0xFTikpIHsKCSAgICAgICAgLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwoJICAgICAgICBzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTjk1LDEpOwoKCSAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwoJICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFx1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcdXNlci5kYXQiKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfQ1VSUkVOVF9VU0VSLFJFR19XSU45NSwxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIC8qIEZJWE1FOiBoZXJlIHdlIHNob3VsZCBjb252ZXJ0IHRvICoucmVnIGZpbGUgc3VwcG9ydGVkIGJ5IHNlcnZlciBhbmQgY2FsbCBSRVFfTE9BRF9SRUdJU1RSWSwgc2VlIFJFR19XSU45NSBjYXNlICovCiAgICAgICAgICAgIF93MzFfbG9hZHJlZygpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfRE9OVExPQUQ6CiAgICAgICAgICAgIFRSQUNFKCJSRUdfRE9OVExPQURcbiIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzd2l0Y2g6IG5vIG1hdGNoICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKCiAgICB9Cn0KCi8qIGxvYWQgZ2xvYmFsIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gL2V0Yy93aW5lKSBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX2dsb2JhbF9yZWdpc3RyeSh2b2lkKQp7CiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICAvKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIEhLRVlfVVNFUlMsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgKTsKCiAgICAvKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgIGxvYWRfd2luZV9yZWdpc3RyeSggSEtFWV9MT0NBTF9NQUNISU5FLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSApOwp9CgovKiBsb2FkIGhvbWUgcmVnaXN0cnkgZmlsZXMgKHN0b3JlZCBpbiB+Ly53aW5lKSBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX2hvbWVfcmVnaXN0cnkoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgTFBDU1RSIGNvbmZkaXIgPSB3aW5lX2dldF9jb25maWdfZGlyKCk7CiAgICBMUFNUUiB0bXAgPSBfeG1hbGxvYyhzdHJsZW4oY29uZmRpcikrMjApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXlfdXNlcnNfZGVmYXVsdCx0bXApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVlfQ1VSUkVOVF9VU0VSLHRtcCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVlfTE9DQUxfTUFDSElORSx0bXApOwoKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgcmVnaXN0cnkgKG5hdGl2ZSBhbmQgZ2xvYmFsIGFuZCBob21lKSAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICAgIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0OwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGlmICghQ0xJRU5UX0lzQm9vdFRocmVhZCgpKSByZXR1cm47ICAvKiBhbHJlYWR5IGxvYWRlZCAqLwoKICAgIGlmIChSZWdDcmVhdGVLZXlBKEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleV91c2Vyc19kZWZhdWx0KSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgSEtFWV9VU0VSUy8uRGVmYXVsdFxuIiApOwogICAgICAgIEV4aXRQcm9jZXNzKDEpOwogICAgfQoKICAgIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMoKTsKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDAsMCwwKTsKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJSZWdpc3RyeSIsIkxvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcyIsMSkpCiAgICAgICAgX2xvYWRfd2luZG93c19yZWdpc3RyeSggaGtleV91c2Vyc19kZWZhdWx0ICk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkR2xvYmFsUmVnaXN0cnlGaWxlcyIsMSkpCiAgICAgICAgX2xvYWRfZ2xvYmFsX3JlZ2lzdHJ5KCk7CiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLDAsMCk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkSG9tZVJlZ2lzdHJ5RmlsZXMiLDEpKQogICAgICAgIF9sb2FkX2hvbWVfcmVnaXN0cnkoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwogICAgX2luaXRfcmVnaXN0cnlfc2F2aW5nKCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICAgIFJlZ0Nsb3NlS2V5KGhrZXlfdXNlcnNfZGVmYXVsdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICBBUEkgRlVOQ1RJT05TICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtBRFZBUEkzMi5AXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleUEgW0FEVkFQSTMyLkBdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX2EobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5QSBbQURWQVBJMzIuQF0KICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIEZJWE1FKCIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl9hKGxwU3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX2EobHBOZXdGaWxlKSxkZWJ1Z3N0cl9hKGxwT2xkRmlsZSkpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgoKCgoKLyogMTYtYml0IGZ1bmN0aW9ucyAqLwoKLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQogKiBzb21lIHByb2dyYW1zLiBEbyBub3QgcmVtb3ZlIHRob3NlIGNhc2VzLiAtTU0KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmaXhfd2luMTZfaGtleSggSEtFWSAqaGtleSApCnsKICAgIGlmICgqaGtleSA9PSAwIHx8ICpoa2V5ID09IDEpICpoa2V5ID0gSEtFWV9DTEFTU0VTX1JPT1Q7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1LZXkgICBbS0VSTkVMLjIxNl0KICogICAgICAgICAgIFJlZ0VudW1LZXkgICBbU0hFTEwuN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIG5hbWUsIERXT1JEIG5hbWVfbGVuICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bUtleUEoIGhrZXksIGluZGV4LCBuYW1lLCBuYW1lX2xlbiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdPcGVuS2V5ICAgW0tFUk5FTC4yMTddCiAqICAgICAgICAgICBSZWdPcGVuS2V5ICAgW1NIRUxMLjFdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnT3BlbktleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDcmVhdGVLZXkgICBbS0VSTkVMLjIxOF0KICogICAgICAgICAgIFJlZ0NyZWF0ZUtleSAgIFtTSEVMTC4yXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZUtleSAgIFtLRVJORUwuMjE5XQogKiAgICAgICAgICAgUmVnRGVsZXRlS2V5ICAgW1NIRUxMLjRdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVLZXlBKCBoa2V5LCBuYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0Nsb3NlS2V5ICAgW0tFUk5FTC4yMjBdCiAqICAgICAgICAgICBSZWdDbG9zZUtleSAgIFtTSEVMTC4zXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlICAgW0tFUk5FTC4yMjFdCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZSAgIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQ1NUUiBkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlQSggaGtleSwgbmFtZSwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRGVsZXRlVmFsdWUgIFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbmFtZSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlQSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdFbnVtVmFsdWUgICBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgdmFsdWUsIExQRFdPUkQgdmFsX2NvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpbmRleCwgdmFsdWUsIHZhbF9jb3VudCwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUgICBbS0VSTkVMLjIyNF0KICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUgICBbU0hFTEwuNl0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUFNUUiBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoY291bnQpICpjb3VudCAmPSAweGZmZmY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoIGhrZXksIG5hbWUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWVFeCAgIFtLRVJORUwuMjI1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnU2V0VmFsdWVFeCAgIFtLRVJORUwuMjI2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgcmVzZXJ2ZWQsIERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIEJZVEUgKmRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoIWNvdW50ICYmICh0eXBlPT1SRUdfU1opKSBjb3VudCA9IHN0cmxlbihkYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4QSggaGtleSwgbmFtZSwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0ZsdXNoS2V5ICAgW0tFUk5FTC4yMjddCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkxNiggSEtFWSBoa2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRmx1c2hLZXkoIGhrZXkgKTsKfQo=