LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxmY250bC5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbm50LmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwocmVnKTsKCi8qIEZJWE1FOiBmb2xsb3dpbmcgZGVmaW5lcyBzaG91bGQgYmUgY29uZmlndXJlZCBnbG9iYWwgKi8KI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICBFVENESVIiL3dpbmUudXNlcnJlZyIKI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgICJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgICJ1c2VyZGVmLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FICJzeXN0ZW0ucmVnIgoKLyogX3htYWxsb2MgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCAqX3htYWxsb2MoIHNpemVfdCBzaXplICkKewogICAgdm9pZCAqcmVzOwoKICAgIHJlcyA9IG1hbGxvYyAoc2l6ZSA/IHNpemUgOiAxKTsKICAgIGlmIChyZXMgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIlZpcnR1YWwgbWVtb3J5IGV4aGF1c3RlZC5cbiIpOwogICAgICAgIGV4aXQgKDEpOwogICAgfQogICAgcmV0dXJuIHJlczsKfQoKLyogX3N0cmR1cG5BIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9zdHJkdXBuQShMUENTVFIgc3RyLHNpemVfdCBsZW4pCnsKICAgIExQU1RSIHJldDsKCiAgICBpZiAoIXN0cikgcmV0dXJuIE5VTEw7CiAgICByZXQgPSBfeG1hbGxvYyggbGVuICsgMSApOwogICAgbWVtY3B5KCByZXQsIHN0ciwgbGVuICk7CiAgICByZXRbbGVuXSA9IDB4MDA7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBXU1RSIF9zdHJkdXBuQXRvVyhMUENTVFIgc3RyQSxzaXplX3QgbGVuQSkKewogICAgTFBXU1RSIHJldDsKICAgIHNpemVfdCBsZW5XOwoKICAgIGlmICghc3RyQSkgcmV0dXJuIE5VTEw7CiAgICBsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsMCxzdHJBLGxlbkEsTlVMTCwwKTsKICAgIHJldCA9IF94bWFsbG9jKGxlblcqc2l6ZW9mKFdDSEFSKStzaXplb2YoV0NIQVIpKTsKICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLDAsc3RyQSxsZW5BLHJldCxsZW5XKTsKICAgIHJldFtsZW5XXSA9IDA7CiAgICByZXR1cm4gcmV0Owp9CgovKiBkdW1wIGEgVW5pY29kZSBzdHJpbmcgd2l0aCBwcm9wZXIgZXNjYXBpbmcgW0ludGVybmFsXSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3VuaWNvZGUuYyAqLwpzdGF0aWMgaW50IF9kdW1wX3N0clcoY29uc3QgV0NIQVIgKnN0cixzaXplX3QgbGVuLEZJTEUgKmYsY2hhciBlc2NhcGVbMl0pCnsKICAgIHN0YXRpYyBjb25zdCBjaGFyIGVzY2FwZXNbMzJdID0gIi4uLi4uLi5hYnRudmZyLi4uLi4uLi4uLi4uLmUuLi4uIjsKICAgIGNoYXIgYnVmZmVyWzI1Nl07CiAgICBMUFNUUiBwb3MgPSBidWZmZXI7CiAgICBpbnQgY291bnQgPSAwOwoKICAgIGZvciAoOyBsZW47IHN0cisrLCBsZW4tLSkKICAgIHsKICAgICAgICBpZiAocG9zID4gYnVmZmVyICsgc2l6ZW9mKGJ1ZmZlcikgLSA4KQogICAgICAgIHsKICAgICAgICAgICAgZndyaXRlKCBidWZmZXIsIHBvcyAtIGJ1ZmZlciwgMSwgZiApOwogICAgICAgICAgICBjb3VudCArPSBwb3MgLSBidWZmZXI7CiAgICAgICAgICAgIHBvcyA9IGJ1ZmZlcjsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPiAxMjcpICAvKiBoZXggZXNjYXBlICovCiAgICAgICAgewogICAgICAgICAgICBpZiAobGVuID4gMSAmJiBzdHJbMV0gPCAxMjggJiYgaXN4ZGlnaXQoKGNoYXIpc3RyWzFdKSkKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHglMDR4IiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFx4JXgiLCAqc3RyICk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA8IDMyKSAgLyogb2N0YWwgb3IgQyBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmICghKnN0ciAmJiBsZW4gPT0gMSkgY29udGludWU7ICAvKiBkbyBub3Qgb3V0cHV0IHRlcm1pbmF0aW5nIE5VTEwgKi8KICAgICAgICAgICAgaWYgKGVzY2FwZXNbKnN0cl0gIT0gJy4nKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxcJWMiLCBlc2NhcGVzWypzdHJdICk7CiAgICAgICAgICAgIGVsc2UgaWYgKGxlbiA+IDEgJiYgc3RyWzFdID49ICcwJyAmJiBzdHJbMV0gPD0gJzcnKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxcJTAzbyIsICpzdHIgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxcJW8iLCAqc3RyICk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA9PSAnXFwnIHx8ICpzdHIgPT0gZXNjYXBlWzBdIHx8ICpzdHIgPT0gZXNjYXBlWzFdKSAqcG9zKysgPSAnXFwnOwogICAgICAgICpwb3MrKyA9ICpzdHI7CiAgICB9CiAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICBjb3VudCArPSBwb3MgLSBidWZmZXI7CiAgICByZXR1cm4gY291bnQ7Cn0KCi8qIGNvbnZlcnQgYW5zaSBzdHJpbmcgdG8gdW5pY29kZSBhbmQgZHVtcCB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyQXRvVyhMUENTVFIgc3RyQSxzaXplX3QgbGVuLEZJTEUgKmYsY2hhciBlc2NhcGVbMl0pCnsKICAgIFdDSEFSICpzdHJXOwogICAgaW50IHJldDsKCiAgICBpZiAoc3RyQSA9PSBOVUxMKSByZXR1cm4gMDsKICAgIHN0clcgPSBfc3RyZHVwbkF0b1coc3RyQSxsZW4pOwogICAgcmV0ID0gX2R1bXBfc3RyVyhzdHJXLGxlbixmLGVzY2FwZSk7CiAgICBmcmVlKHN0clcpOwogICAgcmV0dXJuIHJldDsKfQoKLyogYSBrZXkgdmFsdWUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0cnVjdCBrZXlfdmFsdWUgewogICAgV0NIQVIgICAgICAgICAgICAqbmFtZVc7ICAgLyogdmFsdWUgbmFtZSAqLwogICAgaW50ICAgICAgICAgICAgICAgdHlwZTsgICAgLyogdmFsdWUgdHlwZSAqLwogICAgc2l6ZV90ICAgICAgICAgICAgbGVuOyAgICAgLyogdmFsdWUgZGF0YSBsZW5ndGggaW4gYnl0ZXMgKi8KICAgIHZvaWQgICAgICAgICAgICAgKmRhdGE7ICAgIC8qIHBvaW50ZXIgdG8gdmFsdWUgZGF0YSAqLwp9OwoKLyogZHVtcCBhIHZhbHVlIHRvIGEgdGV4dCBmaWxlICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvcmVnaXN0cnkuYyAqLwpzdGF0aWMgdm9pZCBfZHVtcF92YWx1ZShzdHJ1Y3Qga2V5X3ZhbHVlICp2YWx1ZSxGSUxFICpmKQp7CiAgICBpbnQgaSwgY291bnQ7CgogICAgaWYgKHZhbHVlLT5uYW1lV1swXSkgewogICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgY291bnQgPSAxICsgX2R1bXBfc3RyVyh2YWx1ZS0+bmFtZVcsc3RybGVuVyh2YWx1ZS0+bmFtZVcpLGYsIlwiXCIiKTsKICAgICAgICBjb3VudCArPSBmcHJpbnRmKCBmLCAiXCI9IiApOwogICAgfQogICAgZWxzZSBjb3VudCA9IGZwcmludGYoIGYsICJAPSIgKTsKCiAgICBzd2l0Y2godmFsdWUtPnR5cGUpIHsKICAgICAgICBjYXNlIFJFR19TWjoKICAgICAgICBjYXNlIFJFR19FWFBBTkRfU1o6CiAgICAgICAgY2FzZSBSRUdfTVVMVElfU1o6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+dHlwZSAhPSBSRUdfU1opIGZwcmludGYoIGYsICJzdHIoJWQpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGlmICh2YWx1ZS0+ZGF0YSkgX2R1bXBfc3RyVyh2YWx1ZS0+ZGF0YSx2YWx1ZS0+bGVuL3NpemVvZihXQ0hBUiksZiwiXCJcIiIpOwogICAgICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICAgICAgaWYgKHZhbHVlLT5sZW4gPT0gc2l6ZW9mKERXT1JEKSkgewogICAgICAgICAgICAgICAgRFdPUkQgZHc7CiAgICAgICAgICAgICAgICBtZW1jcHkoICZkdywgdmFsdWUtPmRhdGEsIHNpemVvZihEV09SRCkgKTsKICAgICAgICAgICAgICAgIGZwcmludGYoIGYsICJkd29yZDolMDhseCIsIGR3ICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBlbHNlIGZhbGwgdGhyb3VnaCAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+dHlwZSA9PSBSRUdfQklOQVJZKSBjb3VudCArPSBmcHJpbnRmKCBmLCAiaGV4OiIgKTsKICAgICAgICAgICAgZWxzZSBjb3VudCArPSBmcHJpbnRmKCBmLCAiaGV4KCV4KToiLCB2YWx1ZS0+dHlwZSApOwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUtPmxlbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBjb3VudCArPSBmcHJpbnRmKCBmLCAiJTAyeCIsICooKHVuc2lnbmVkIGNoYXIgKil2YWx1ZS0+ZGF0YSArIGkpICk7CiAgICAgICAgICAgICAgICBpZiAoaSA8IHZhbHVlLT5sZW4tMSkgewogICAgICAgICAgICAgICAgICAgIGZwdXRjKCAnLCcsIGYgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoKytjb3VudCA+IDc2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoIGYsICJcXFxuICAiICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBmcHV0YyggJ1xuJywgZiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwovKgogICAgcmVnaGFjayAtIHdpbmRvd3MgMy4xMSByZWdpc3RyeSBkYXRhIGZvcm1hdCBkZW1vIHByb2dyYW0uCgogICAgVGhlIHJlZy5kYXQgZmlsZSBoYXMgMyBwYXJ0cywgYSBoZWFkZXIsIGEgdGFibGUgb2YgOC1ieXRlIGVudHJpZXMgdGhhdCBpcwogICAgYSBjb21iaW5lZCBoYXNoIHRhYmxlIGFuZCB0cmVlIGRlc2NyaXB0aW9uLCBhbmQgZmluYWxseSBhIHRleHQgdGFibGUuCgogICAgVGhlIGhlYWRlciBpcyBvYnZpb3VzIGZyb20gdGhlIHN0cnVjdCBoZWFkZXIuIFRoZSB0YWJvZmYxIGFuZCB0YWJvZmYyCiAgICBmaWVsZHMgYXJlIGFsd2F5cyAweDIwLCBhbmQgdGhlaXIgdXNhZ2UgaXMgdW5rbm93bi4KCiAgICBUaGUgOC1ieXRlIGVudHJ5IHRhYmxlIGhhcyB2YXJpb3VzIGVudHJ5IHR5cGVzLgoKICAgIHRhYmVudFswXSBpcyBhIHJvb3QgaW5kZXguIFRoZSBzZWNvbmQgd29yZCBoYXMgdGhlIGluZGV4IG9mIHRoZSByb290IG9mCiAgICAgICAgICAgIHRoZSBkaXJlY3RvcnkuCiAgICB0YWJlbnRbMS4uaGFzaHNpemVdIGlzIGEgaGFzaCB0YWJsZS4gVGhlIGZpcnN0IHdvcmQgaW4gdGhlIGhhc2ggZW50cnkgaXMKICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBrZXkvdmFsdWUgdGhhdCBoYXMgdGhhdCBoYXNoLiBEYXRhIHdpdGggdGhlIHNhbWUKICAgICAgICAgICAgaGFzaCB2YWx1ZSBhcmUgb24gYSBjaXJjdWxhciBsaXN0LiBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlCiAgICAgICAgICAgIGhhc2ggZW50cnkgYXJlIGFsd2F5cyB6ZXJvLgogICAgdGFiZW50W2hhc2hzaXplLi50YWJjbnRdIGlzIHRoZSB0cmVlIHN0cnVjdHVyZS4gVGhlcmUgYXJlIHR3byBraW5kcyBvZgogICAgICAgICAgICBlbnRyeTogZGlyZW50IGFuZCBrZXllbnQvdmFsZW50LiBUaGV5IGFyZSBpZGVudGlmaWVkIGJ5IGNvbnRleHQuCiAgICB0YWJlbnRbZnJlZWlkeF0gaXMgdGhlIGZpcnN0IGZyZWUgZW50cnkuIFRoZSBmaXJzdCB3b3JkIGluIGEgZnJlZSBlbnRyeQogICAgICAgICAgICBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgZnJlZSBlbnRyeS4gVGhlIGxhc3QgaGFzIDAgYXMgYSBsaW5rLgogICAgICAgICAgICBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlIGZyZWUgbGlzdCBhcmUgcHJvYmFibHkgaXJyZWxldmFudC4KCiAgICBFbnRyaWVzIGluIHRleHQgdGFibGUgYXJlIHByZWNlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKICAgIGNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwogICAgdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwogICAgdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewogICAgdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewogICAgdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewogICAgdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICBbSW50ZXJuYWxdICovCnZvaWQgX3czMV9kdW1wdHJlZSh1bnNpZ25lZCBzaG9ydCBpZHgsdW5zaWduZWQgY2hhciAqdHh0LHN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLHN0cnVjdCBfdzMxX2hlYWRlciAqaGVhZCxIS0VZIGhrZXksdGltZV90IGxhc3Rtb2RpZmllZCwgaW50IGxldmVsKQp7CiAgICBzdHJ1Y3QgX3czMV9kaXJlbnQgKmRpcjsKICAgIHN0cnVjdCBfdzMxX2tleWVudCAqa2V5OwogICAgc3RydWN0IF93MzFfdmFsZW50ICp2YWw7CiAgICBIS0VZIHN1YmtleSA9IDA7CiAgICBzdGF0aWMgY2hhcgl0YWlsWzQwMF07CgogICAgd2hpbGUgKGlkeCE9MCkgewogICAgICAgIGRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgogICAgICAgIGlmIChkaXItPmtleV9pZHgpIHsKICAgICAgICAgICAga2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKICAgICAgICAgICAgbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKICAgICAgICAgICAgdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKICAgICAgICAgICAgLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKICAgICAgICAgICAgICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhc3RyY21wKHRhaWwsIi5jbGFzc2VzIikpIHsKICAgICAgICAgICAgICAgIF93MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGhrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgICAgICAgICAgaWR4PWRpci0+c2libGluZ19pZHg7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CiAgICAgICAgICAgIGlmIChSZWdDcmVhdGVLZXlBKCBoa2V5LCB0YWlsLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKICAgICAgICAgICAgLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCiAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKICAgICAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCkgewogICAgICAgICAgICAgICAgICAgIHZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKICAgICAgICAgICAgICAgICAgICBtZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIHRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWVBKCBzdWJrZXksIE5VTEwsIFJFR19TWiwgdGFpbCwgMCApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIFRSQUNFKCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwogICAgICAgIF93MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHN1YmtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgaWR4PWRpci0+c2libGluZ19pZHg7CiAgICB9CiAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZyh2b2lkKSAKewogICAgSEZJTEUgaGY7CiAgICBzdHJ1Y3QgX3czMV9oZWFkZXIJaGVhZDsKICAgIHN0cnVjdCBfdzMxX3RhYmVudAkqdGFiOwogICAgdW5zaWduZWQgY2hhcgkJKnR4dDsKICAgIHVuc2lnbmVkIGludAkJbGVuOwogICAgT0ZTVFJVQ1QJCW9mczsKICAgIEJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKICAgIHRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBoZiA9IE9wZW5GaWxlKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwogICAgaWYgKGhmPT1IRklMRV9FUlJPUikgcmV0dXJuOwoKICAgIC8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwogICAgaWYgKHNpemVvZihoZWFkKSE9X2xyZWFkKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKICAgICAgICBFUlIoInJlZy5kYXQgaXMgdG9vIHNob3J0LlxuIik7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKICAgICAgICBFUlIoInJlZy5kYXQgaGFzIGJhZCBzaWduYXR1cmUuXG4iKTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKICAgIC8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KICAgIHRhYiA9IF94bWFsbG9jKGxlbik7CiAgICBpZiAobGVuIT1fbHJlYWQoaGYsdGFiLGxlbikpIHsKICAgICAgICBFUlIoImNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogcmVhZCB0ZXh0ICovCiAgICB0eHQgPSBfeG1hbGxvYyhoZWFkLnRleHRzaXplKTsKICAgIGlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CiAgICAgICAgRVJSKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCiAgICAgICAgZnJlZSh0YWIpOwogICAgICAgIGZyZWUodHh0KTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewogICAgICAgIEVSUigiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKICAgIF93MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsSEtFWV9DTEFTU0VTX1JPT1QsbGFzdG1vZGlmaWVkLDApOwogICAgZnJlZSh0YWIpOwogICAgZnJlZSh0eHQpOwogICAgX2xjbG9zZShoZik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogIkNSRUciID0gVzk1X1JFR19DUkVHX0lEICovCiAgICBEV09SRAl2ZXJzaW9uOwkvKiA/Pz8/IDB4MDAwMTAwMDAgKi8KICAgIERXT1JECXJnZGJfb2ZmOwkvKiAweDA4IE9mZnNldCBvZiAxc3QgUkdEQi1ibG9jayAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwYyAqLwogICAgV09SRAlyZ2RiX251bTsJLyogMHgxMCAjIG9mIFJHREItYmxvY2tzICovCiAgICBXT1JECXVrMzsKICAgIERXT1JECXVrWzNdOwogICAgLyogcmdrbiAqLwp9IF93OTVjcmVnOwoKLyogU0VDVElPTiAyOiBEaXJlY3RvcnkgaW5mb3JtYXRpb24gKHRyZWUgc3RydWN0dXJlKQogKgogKiBvbmNlIG9uIG9mZnNldCAweDIwCiAqCiAqIHN0cnVjdHVyZTogW3Jna25dW2RrZV0qCShyZXBlYXQgdGlsbCBsYXN0X2RrZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KICAgIERXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KICAgIERXT1JEICAgbGFzdF9ka2U7ICAgICAgIC8qIE9mZnNldCB0byBsYXN0IERLRSA/ICovCiAgICBEV09SRAl1a1s0XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMgCiAqIG9mIHRoZSBzdHJpbmcgd2hpY2ggYXJlIHNtYWxsZXIgdGhhbiAweDgwICgxMjgpIHRvIHRoaXMgRC1Xb3JkLiAgIAogKgogKiBJZiB5b3Ugd2FudCB0byBtb2RpZnkga2V5IG5hbWVzLCBhbHNvIG1vZGlmeSB0aGUgaGFzaC12YWx1ZXMsIHNpbmNlIHRoZXkKICogY2Fubm90IGJlIGZvdW5kIGFnYWluIChhbHRob3VnaCB0aGV5IHdvdWxkIGJlIGRpc3BsYXllZCBpbiBSRUdFRElUKQogKiBFbmQgb2YgbGlzdC1wb2ludGVycyBhcmUgZmlsbGVkIHdpdGggMHhGRkZGRkZGRgogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJNUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICoKICogVGhlIGxhc3QgREtFIChzZWUgZmllbGQgbGFzdF9ka2UgaW4gX3c5NV9yZ2tuKSBoYXMgb25seSAzIERXT1JEcyB3aXRoCiAqIDB4ODAwMDAwMDAgKEVPTCBpbmRpY2F0b3IgPykgYXMgeDEsIHRoZSBoYXNoIHZhbHVlIGFuZCAweEZGRkZGRkZGIGFzIHgzLgogKiBUaGUgcmVtYWluaW5nIHNwYWNlIGJldHdlZW4gbGFzdF9ka2UgYW5kIHRoZSBvZmZzZXQgY2FsY3VsYXRlZCBmcm9tCiAqIHJna24tPnNpemUgc2VlbXMgdG8gYmUgZnJlZSBmb3IgdXNlIGZvciBtb3JlIGRrZTpzLgogKiBTbyBpdCBzZWVtcyBpZiBtb3JlIGRrZTpzIGFyZSBhZGRlZCwgdGhleSBhcmUgYWRkZWQgdG8gdGhhdCBzcGFjZSBhbmQKICogbGFzdF9ka2UgaXMgZ3Jvd24sIGFuZCBpbiBjYXNlIHRoYXQgImZyZWUiIHNwYWNlIGlzIG91dCwgdGhlIHNwYWNlCiAqIGdldHMgZ3Jvd24gYW5kIHJna24tPnNpemUgZ2V0cyBhZGp1c3RlZC4KICoKICogdGhlcmUgaXMgYSBvbmUgdG8gb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRrZSBhbmQgZGtoCiAqLwogLyoga2V5IHN0cnVjdCwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECXgxOwkJLyogRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykgKi8KICAgIERXT1JECWhhc2g7CQkvKiBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZSAqLwogICAgRFdPUkQJeDM7CQkvKiBSb290IGtleSBpbmRpY2F0b3I/IHVzdWFsbHkgMHhGRkZGRkZGRiAqLwogICAgRFdPUkQJcHJldmx2bDsJLyogb2Zmc2V0IG9mIHByZXZpb3VzIGtleSAqLwogICAgRFdPUkQJbmV4dHN1YjsJLyogb2Zmc2V0IG9mIGNoaWxkIGtleSAqLwogICAgRFdPUkQJbmV4dDsJCS8qIG9mZnNldCBvZiBzaWJsaW5nIGtleSAqLwogICAgV09SRAluckxTOwkJLyogaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KfSBfdzk1ZGtlOwoKLyogU0VDVElPTiAzOiBrZXkgaW5mb3JtYXRpb24sIHZhbHVlcyBhbmQgZGF0YQogKgogKiBzdHJ1Y3R1cmU6CiAqICBzZWN0aW9uOglbYmxvY2tzXSoJCShyZXBlYXQgY3JlZy0+cmdkYl9udW0gdGltZXMpCiAqICBibG9ja3M6CVtyZ2RiXSBbc3ViYmxvY2tzXSogCShyZXBlYXQgdGlsbCBibG9jayBzaXplIHJlYWNoZWQgKQogKiAgc3ViYmxvY2tzOglbZGtoXSBbZGt2XSoJCShyZXBlYXQgZGtoLT52YWx1ZXMgdGltZXMgKQogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIERXT1JEIHZhbHVlCiAqIGF0IG9mZnNldCAweDEwIGVxdWFscyB0aGUgb25lIGF0IG9mZnNldCAweDA0IG1pbnVzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDguCiAqIEkgaGF2ZSBubyBpZGVhIGF0IHRoZSBtb21lbnQgd2hhdCB0aGlzIG1lYW5zLiAgKEtldmluIENvemVucykKICovCgovKiBibG9jayBoZWFkZXIsIG9uY2UgcGVyIGJsb2NrICovCiNkZWZpbmUgVzk1X1JFR19SR0RCX0lECTB4NDI0NDQ3NTIKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkvKiAweDAwICdSR0RCJyA9IFc5NV9SRUdfUkdEQl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkvKiAweDA4ICovCiAgICBEV09SRAl1azI7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJLyogMHgxMCAqLwogICAgRFdPUkQJdWs0OwkvKiAweDE0ICovCiAgICBEV09SRAl1azU7CS8qIDB4MTggKi8KICAgIERXT1JECXVrNjsJLyogMHgxYyAqLwogICAgLyogZGtoICovCn0gX3c5NXJnZGI7CgovKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpLCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZglzdHJ1Y3QgewogICAgRFdPUkQJbmV4dGtleW9mZjsgCS8qIDB4MDAgb2Zmc2V0IHRvIG5leHQgZGtoICovCiAgICBXT1JECW5yTFM7CQkvKiAweDA0IGlkIGluc2lkZSB0aGUgcmdkYiBibG9jayAqLwogICAgV09SRAluck1TOwkJLyogMHgwNiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KICAgIERXT1JECWJ5dGVzdXNlZDsJLyogMHgwOCAqLwogICAgV09SRAlrZXluYW1lbGVuOwkvKiAweDBjIGxlbiBvZiBuYW1lICovCiAgICBXT1JECXZhbHVlczsJCS8qIDB4MGUgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJeHgxOwkJLyogMHgxMCAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDE0ICovCiAgICAvKiBka3YgKi8JCS8qIDB4MTQgKyBrZXluYW1lbGVuICovCn0gX3c5NWRraDsKCi8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSwgb25jZSBwZXIgdmFsdWUgKi8KdHlwZWRlZglzdHJ1Y3QgewogICAgRFdPUkQJdHlwZTsJCS8qIDB4MDAgKi8KICAgIERXT1JECXgxOwkJLyogMHgwNCAqLwogICAgV09SRAl2YWxuYW1lbGVuOwkvKiAweDA4IGxlbmd0aCBvZiBuYW1lLCAwIGlzIGRlZmF1bHQga2V5ICovCiAgICBXT1JECXZhbGRhdGFsZW47CS8qIDB4MEEgbGVuZ3RoIG9mIGRhdGEgKi8KICAgIGNoYXIJbmFtZVsxXTsJLyogMHgwYyAqLwogICAgLyogcmF3IGRhdGEgKi8JCS8qIDB4MGMgKyB2YWxuYW1lbGVuICovCn0gX3c5NWRrdjsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9sb29rdXBfZGtoIFtJbnRlcm5hbF0KICoKICogc2Vla3MgdGhlIGRraCBiZWxvbmdpbmcgdG8gYSBka2UKICovCnN0YXRpYyBfdzk1ZGtoICpfdzk1X2xvb2t1cF9ka2goX3c5NWNyZWcgKmNyZWcsaW50IG5yTFMsaW50IG5yTVMpCnsKICAgIF93OTVyZ2RiICogcmdkYjsKICAgIF93OTVka2ggKiBka2g7CiAgICBpbnQgaTsKCiAgICAvKiBnZXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcmdkYiBkYXRhc3RvcmUgKi8KICAgIHJnZGIgPSAoX3c5NXJnZGIqKSgoY2hhciopY3JlZytjcmVnLT5yZ2RiX29mZik7CgogICAgLyogY2hlY2s6IHJlcXVlc3RlZCBibG9jayA8IGxhc3RfYmxvY2spICovCiAgICBpZiAoY3JlZy0+cmdkYl9udW0gPD0gbnJNUykgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZXF1ZXN0ZWQgYmxvY2sgbm8uIGJleW9uZCBlbmQuXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIGZpbmQgdGhlIHJpZ2h0IGJsb2NrICovCiAgICBmb3IoaT0wOyBpPG5yTVMgO2krKykgewogICAgICAgIGlmKHJnZGItPmlkICE9IFc5NV9SRUdfUkdEQl9JRCkgeyAgLyogY2hlY2sgdGhlIG1hZ2ljICovCiAgICAgICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBiYWQgbWFnaWMgMHglMDhseFxuIiwgcmdkYi0+aWQpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICByZ2RiID0gKF93OTVyZ2RiKikgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpOwkJLyogZmluZCBuZXh0IGJsb2NrICovCiAgICB9CgogICAgZGtoID0gKF93OTVka2gqKShyZ2RiICsgMSk7CQkJCS8qIGZpcnN0IHN1YiBibG9jayB3aXRoaW4gdGhlIHJnZGIgKi8KCiAgICBkbyB7CiAgICAgICAgaWYobnJMUz09ZGtoLT5uckxTICkgcmV0dXJuIGRraDsKICAgICAgICBka2ggPSAoX3c5NWRraCopKChjaGFyKilka2ggKyBka2gtPm5leHRrZXlvZmYpOwkvKiBmaW5kIG5leHQgc3ViYmxvY2sgKi8KICAgIH0gd2hpbGUgKChjaGFyICopZGtoIDwgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpKTsKCmVycm9yOgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrdiBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka3YoX3c5NWRraCAqZGtoLGludCBuckxTLGludCBuck1TLEZJTEUgKmYpCnsKICAgIF93OTVka3YgKiBka3Y7CiAgICBpbnQgaTsKCiAgICAvKiBmaXJzdCB2YWx1ZSBibG9jayAqLwogICAgZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGtoK2RraC0+a2V5bmFtZWxlbisweDE0KTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHZhbHVlcyAqLwogICAgZm9yIChpPTA7IGk8IGRraC0+dmFsdWVzOyBpKyspIHsKICAgICAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwogICAgICAgIFdDSEFSICpwZGF0YTsKCiAgICAgICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1coZGt2LT5uYW1lLGRrdi0+dmFsbmFtZWxlbik7CiAgICAgICAgdmFsdWUudHlwZSA9IGRrdi0+dHlwZTsKICAgICAgICB2YWx1ZS5sZW4gPSBka3YtPnZhbGRhdGFsZW47CgogICAgICAgIHZhbHVlLmRhdGEgPSAmKGRrdi0+bmFtZVtka3YtPnZhbG5hbWVsZW5dKTsKICAgICAgICBwZGF0YSA9IE5VTEw7CiAgICAgICAgaWYgKCAodmFsdWUudHlwZT09UkVHX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX0VYUEFORF9TWikgfHwgKHZhbHVlLnR5cGU9PVJFR19NVUxUSV9TWikgKSB7CiAgICAgICAgICAgIHBkYXRhID0gX3N0cmR1cG5BdG9XKHZhbHVlLmRhdGEsdmFsdWUubGVuKTsKICAgICAgICAgICAgdmFsdWUubGVuICo9IDI7CiAgICAgICAgfQogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSB2YWx1ZS5kYXRhID0gcGRhdGE7CgogICAgICAgIF9kdW1wX3ZhbHVlKCZ2YWx1ZSxmKTsKICAgICAgICBmcmVlKHZhbHVlLm5hbWVXKTsKICAgICAgICBpZiAocGRhdGEgIT0gTlVMTCkgZnJlZShwZGF0YSk7CgogICAgICAgIC8qIG5leHQgdmFsdWUgKi8KICAgICAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka3YrZGt2LT52YWxuYW1lbGVuK2Rrdi0+dmFsZGF0YWxlbisweDBjKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfZHVtcF9ka2UgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X2R1bXBfZGtlKExQU1RSIGtleV9uYW1lLF93OTVjcmVnICpjcmVnLF93OTVyZ2tuICpyZ2tuLF93OTVka2UgKmRrZSxGSUxFICpmLGludCBsZXZlbCkKewogICAgX3c5NWRraCAqIGRraDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgogICAgLyogc3BlY2lhbCByb290IGtleSAqLwogICAgaWYgKGRrZS0+bnJMUyA9PSAweGZmZmYgfHwgZGtlLT5uck1TPT0weGZmZmYpCQkvKiBlZy4gdGhlIHJvb3Qga2V5IGhhcyBubyBuYW1lICovCiAgICB7CiAgICAgICAgLyogcGFyc2UgdGhlIG9uZSBzdWJrZXkgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHJldHVybiBfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbCk7CiAgICAgICAgLyogaGFzIG5vIHNpYmxpbmcga2V5cyAqLwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBzZWFyY2ggc3ViYmxvY2sgKi8KICAgIGlmICghKGRraCA9IF93OTVfbG9va3VwX2RraChjcmVnLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpKSB7CiAgICAgICAgRVJSKCJka2UgcG9pbnRpbmcgdG8gbWlzc2luZyBka2ggIVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpK2RraC0+a2V5bmFtZWxlbisxKTsKICAgICAgICBpZiAoc3RyY21wKG5ld19rZXlfbmFtZSwiIikgIT0gMCkgc3RyY2F0KG5ld19rZXlfbmFtZSwiXFwiKTsKICAgICAgICBzdHJuY2F0KG5ld19rZXlfbmFtZSxka2gtPm5hbWUsZGtoLT5rZXluYW1lbGVuKTsKCiAgICAgICAgLyogd2FsayBzaWJsaW5nIGtleXMgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYgKSB7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShrZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHQpLGYsbGV2ZWwpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjogCiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAoZGtoLT52YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgICAgICBpZiAoIV93OTVfZHVtcF9ka3YoZGtoLCBka2UtPm5yTFMsIGRrZS0+bnJNUyxmKSkgewogICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKChka2UtPm5leHRzdWIgPT0gMHhmZmZmZmZmZikgJiYgKGRraC0+dmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfc3RyZHVwbkEoa2V5X25hbWUsc3RybGVuKGtleV9uYW1lKSk7CgogICAgLyogbmV4dCBzdWIga2V5ICovCiAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHsKICAgICAgICBpZiAoIV93OTVfZHVtcF9ka2UobmV3X2tleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbC0xKSkgewogICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQovKiBlbmQgd2luZG93cyA5NSBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIE5UIHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBOVCBSRUdJU1RSWSBMT0FERVIgKi8KCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpZm5kZWYgTUFQX0ZBSUxFRAojZGVmaW5lIE1BUF9GQUlMRUQgKChMUFZPSUQpLTEpCiNlbmRpZgoKI2RlZmluZSBOVF9SRUdfQkxPQ0tfU0laRSAgICAgICAgICAgIDB4MTAwMAoKI2RlZmluZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEICAgICAgIDB4NjY2NzY1NzIJLyogcmVnZiAqLwojZGVmaW5lIE5UX1JFR19QT09MX0JMT0NLX0lEICAgICAgICAgMHg2RTY5NjI2OAkvKiBoYmluICovCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19JRCAgICAgICAgICAweDZiNmUgLyogbmsgKi8KI2RlZmluZSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQgICAgICAgIDB4NmI3NiAvKiB2ayAqLwoKLyogc3ViYmxvY2tzIG9mIG5rICovCiNkZWZpbmUgTlRfUkVHX0hBU0hfQkxPQ0tfSUQgICAgICAgICAweDY2NmMgLyogbGYgKi8KI2RlZmluZSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEICAgICAgIDB4Njk2YyAvKiBsaSAqLwojZGVmaW5lIE5UX1JFR19SSV9CTE9DS19JRAkgICAgIDB4Njk3MiAvKiByaSAqLwoKI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX1RZUEUgICAgICAgIDB4MjAKI2RlZmluZSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSAgIDB4MmMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2NjY3NjU3MiAncmVnZicqLwogICAgRFdPUkQJdWsxOwkJLyogMHgwNCAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwOCAqLwogICAgRklMRVRJTUUJRGF0ZU1vZGlmaWVkOwkvKiAweDBjICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAl1azU7CQkvKiAweDFjICovCiAgICBEV09SRAl1azY7CQkvKiAweDIwICovCiAgICBEV09SRAlSb290S2V5QmxvY2s7CS8qIDB4MjQgKi8KICAgIERXT1JECUJsb2NrU2l6ZTsJLyogMHgyOCAqLwogICAgRFdPUkQgICB1azdbMTE2XTsJCiAgICBEV09SRAlDaGVja3N1bTsgLyogYXQgb2Zmc2V0IDB4MUZDICovCn0gbnRfcmVnZjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWJsb2Nrc2l6ZTsKICAgIEJZVEUJZGF0YVsxXTsKfSBudF9oYmluX3N1YjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2RTY5NjI2OCAnaGJpbicgKi8KICAgIERXT1JECW9mZl9wcmV2OwogICAgRFdPUkQJb2ZmX25leHQ7CiAgICBEV09SRAl1azE7CiAgICBEV09SRAl1azI7CQkvKiAweDEwICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAlzaXplOwkJLyogMHgxQyAqLwogICAgbnRfaGJpbl9zdWIJaGJpbl9zdWI7CS8qIDB4MjAgKi8KfSBudF9oYmluOwoKLyoKICogdGhlIHZhbHVlX2xpc3QgY29uc2lzdHMgb2Ygb2Zmc2V0cyB0byB0aGUgdmFsdWVzICh2aykKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJU3ViQmxvY2tJZDsJCS8qIDB4MDAgMHg2QjZFICovCiAgICBXT1JECVR5cGU7CQkJLyogMHgwMiBmb3IgdGhlIHJvb3Qta2V5OiAweDJDLCBvdGhlcndpc2UgMHgyMCovCiAgICBGSUxFVElNRQl3cml0ZXRpbWU7CS8qIDB4MDQgKi8KICAgIERXT1JECXVrMTsJCQkvKiAweDBDICovCiAgICBEV09SRAlwYXJlbnRfb2ZmOwkJLyogMHgxMCBPZmZzZXQgb2YgT3duZXIvUGFyZW50IGtleSAqLwogICAgRFdPUkQJbnJfc3Via2V5czsJCS8qIDB4MTQgbnVtYmVyIG9mIHN1Yi1LZXlzICovCiAgICBEV09SRAl1azg7CQkJLyogMHgxOCAqLwogICAgRFdPUkQJbGZfb2ZmOwkJCS8qIDB4MUMgT2Zmc2V0IG9mIHRoZSBzdWIta2V5IGxmLVJlY29yZHMgKi8KICAgIERXT1JECXVrMjsJCQkvKiAweDIwICovCiAgICBEV09SRAlucl92YWx1ZXM7CQkvKiAweDI0IG51bWJlciBvZiB2YWx1ZXMgKi8KICAgIERXT1JECXZhbHVlbGlzdF9vZmY7CQkvKiAweDI4IE9mZnNldCBvZiB0aGUgVmFsdWUtTGlzdCAqLwogICAgRFdPUkQJb2ZmX3NrOwkJCS8qIDB4MmMgT2Zmc2V0IG9mIHRoZSBzay1SZWNvcmQgKi8KICAgIERXT1JECW9mZl9jbGFzczsJCS8qIDB4MzAgT2Zmc2V0IG9mIHRoZSBDbGFzcy1OYW1lICovCiAgICBEV09SRAl1azM7CQkJLyogMHgzNCAqLwogICAgRFdPUkQJdWs0OwkJCS8qIDB4MzggKi8KICAgIERXT1JECXVrNTsJCQkvKiAweDNjICovCiAgICBEV09SRAl1azY7CQkJLyogMHg0MCAqLwogICAgRFdPUkQJdWs3OwkJCS8qIDB4NDQgKi8KICAgIFdPUkQJbmFtZV9sZW47CQkvKiAweDQ4IG5hbWUtbGVuZ3RoICovCiAgICBXT1JECWNsYXNzX2xlbjsJCS8qIDB4NGEgY2xhc3MtbmFtZSBsZW5ndGggKi8KICAgIGNoYXIJbmFtZVsxXTsJCS8qIDB4NGMga2V5LW5hbWUgKi8KfSBudF9uazsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECW9mZl9uazsJLyogMHgwMCAqLwogICAgRFdPUkQJbmFtZTsJLyogMHgwNCAqLwp9IGhhc2hfcmVjOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2NjZjICovCiAgICBXT1JECW5yX2tleXM7CS8qIDB4MDYgKi8KICAgIGhhc2hfcmVjCWhhc2hfcmVjWzFdOwp9IG50X2xmOwoKLyoKIGxpc3Qgb2Ygc3Via2V5cyB3aXRob3V0IGhhc2gKCiBsaSAtLSstLT5uawogICAgICB8CiAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTZjICovCiAgICBXT1JECW5yX2tleXM7CiAgICBEV09SRAlvZmZfbmtbMV07Cn0gbnRfbGk7CgovKgogdGhpcyBpcyBhIGludGVybWVkaWF0ZSBub2RlCgogcmkgLS0rLS0+bGktLSstLT5uawogICAgICB8ICAgICAgICsKICAgICAgfCAgICAgICArLS0+bmsKICAgICAgfAogICAgICArLS0+bGktLSstLT5uawogICAgICAgICAgICAgICsKCSAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTcyICovCiAgICBXT1JECW5yX2xpOwkJLyogMHgwMiBudW1iZXIgb2ZmIG9mZnNldHMgKi8KICAgIERXT1JECW9mZl9saVsxXTsJLyogMHgwNCBwb2ludHMgdG8gbGkgKi8KfSBudF9yaTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwICd2aycgKi8KICAgIFdPUkQJbmFtX2xlbjsKICAgIERXT1JECWRhdGFfbGVuOwogICAgRFdPUkQJZGF0YV9vZmY7CiAgICBEV09SRAl0eXBlOwogICAgV09SRAlmbGFnOwogICAgV09SRAl1azE7CiAgICBjaGFyCW5hbWVbMV07Cn0gbnRfdms7CgovKgogKiBnZXRzIGEgdmFsdWUKICoKICogdmstPmZsYWc6CiAqICAwIHZhbHVlIGlzIGEgZGVmYXVsdCB2YWx1ZQogKiAgMSB0aGUgdmFsdWUgaGFzIGEgbmFtZQogKgogKiB2ay0+ZGF0YV9sZW4KICogIGxlbiBvZiB0aGUgd2hvbGUgZGF0YSBibG9jawogKiAgLSByZWdfc3ogKHVuaWNvZGUpCiAqICAgIGJ5dGVzIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgXDAgPSAyKihudW1iZXJfb2ZfY2hhcnMrMSkKICogIC0gcmVnX2R3b3JkLCByZWdfYmluYXJ5OgogKiAgICBpZiBoaWdoZXN0IGJpdCBvZiBkYXRhX2xlbiBpcyBzZXQgZGF0YV9vZmYgY29udGFpbnMgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX3ZrKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBudF92ayAqdmssRklMRSAqZikKewogICAgQllURSAqcGRhdGEgPSAoQllURSAqKShiYXNlK3ZrLT5kYXRhX29mZis0KTsgLyogc3RhcnQgb2YgZGF0YSAqLwogICAgc3RydWN0IGtleV92YWx1ZSB2YWx1ZTsKCiAgICBpZiAodmstPmlkICE9IE5UX1JFR19WQUxVRV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBibG9jayBmb3VuZCAoMHglMDR4KSwgcGxlYXNlIHJlcG9ydCFcbiIsIHZrLT5pZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHZhbHVlLm5hbWVXID0gX3N0cmR1cG5BdG9XKHZrLT5uYW1lLHZrLT5uYW1fbGVuKTsKICAgIHZhbHVlLnR5cGUgPSB2ay0+dHlwZTsKICAgIHZhbHVlLmxlbiA9ICh2ay0+ZGF0YV9sZW4gJiAweDdmZmZmZmZmKTsKICAgIHZhbHVlLmRhdGEgPSAodmstPmRhdGFfbGVuICYgMHg4MDAwMDAwMCkgPyAoTFBCWVRFKSYodmstPmRhdGFfb2ZmKTogcGRhdGE7CgogICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgZnJlZSh2YWx1ZS5uYW1lVyk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGl0J3MgY2FsbGVkIGZyb20gX250X2R1bXBfbGYoKSAqLwpzdGF0aWMgaW50IF9udF9kdW1wX25rKExQU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKTsKCi8qCiAqIGdldCB0aGUgc3Via2V5cwogKgogKiB0aGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgaGFzaCBvZiBhIGtleW5hbWUgYW5kIHBvaW50cyB0byBhbGwKICogc3Via2V5cwogKgogKiBleGNlcHRpb246IGlmIHRoZSBpZCBpcyAnaWwnIHRoZXJlIGFyZSBubyBoYXNoIHZhbHVlcyBhbmQgZXZlcnkgCiAqIGR3b3JkIGlzIGEgb2Zmc2V0CiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX2xmKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKmxmLCBGSUxFICpmLCBpbnQgbGV2ZWwpCnsKICAgIGludCBpOwogICAgCiAgICBpZiAobGYtPmlkID09IE5UX1JFR19IQVNIX0JMT0NLX0lEKSB7CiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGYtPm5yX2tleXMpIGdvdG8gZXJyb3IxOwogICAgCiAgICAgICAgZm9yIChpPTA7IGk8bGYtPm5yX2tleXM7IGkrKykgCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgewogICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIHsgIC8qIHJpICovCiAgICAgICAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CiAgICAgICAgaW50IGxpX3N1YmtleXMgPSAwOwoKICAgICAgICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKICAgICAgICAgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIG51bWJlciAqLwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfbGYoa2V5X25hbWUsIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfSBlbHNlIGdvdG8gZXJyb3IyOwoKICAgIHJldHVybiBUUlVFOwoKZXJyb3IyOgogICAgRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbGYtPmlkKTsKICAgIHJldHVybiBUUlVFOwoKZXJyb3IxOgogICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIChpbmNvbnNpc3RlbnQgbnVtYmVyIG9mIHN1YmtleXMpXG4iKTsKICAgIHJldHVybiBGQUxTRTsKCmVycm9yOgogICAgRVJSKCJlcnJvciByZWFkaW5nIGxmIGJsb2NrXG4iKTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyogX250X2R1bXBfbmsgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9udF9kdW1wX25rKExQU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICB1bnNpZ25lZCBpbnQgbjsKICAgIERXT1JEICp2bDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgoKICAgIGlmIChuay0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbmstPlN1YkJsb2NrSWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKG5rLT5UeXBlIT1OVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgJiYgKCgobnRfbmsqKShiYXNlK25rLT5wYXJlbnRfb2ZmKzQpKS0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSkgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0IVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIGNyZWF0ZSB0aGUgbmV3IGtleSAqLwogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkrbmstPm5hbWVfbGVuKzEpOwogICAgICAgIGlmIChzdHJjbXAobmV3X2tleV9uYW1lLCIiKSAhPSAwKSBzdHJjYXQobmV3X2tleV9uYW1lLCJcXCIpOwogICAgICAgIHN0cm5jYXQobmV3X2tleV9uYW1lLG5rLT5uYW1lLG5rLT5uYW1lX2xlbik7CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjogCiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAobmstPm5yX3ZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgICAgIGlmICgobmstPm5yX3N1YmtleXMgPT0gMCkgJiYgKG5rLT5ucl92YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQoKICAgICAgICAvKiBsb29wIHRyb3VnaCB0aGUgdmFsdWUgbGlzdCAqLwogICAgICAgIHZsID0gKERXT1JEICopKGJhc2UrbmstPnZhbHVlbGlzdF9vZmYrNCk7CiAgICAgICAgZm9yIChuPTA7IG48bmstPm5yX3ZhbHVlczsgbisrKSB7CiAgICAgICAgICAgIG50X3ZrICogdmsgPSAobnRfdmsqKShiYXNlK3ZsW25dKzQpOwogICAgICAgICAgICBpZiAoIV9udF9kdW1wX3ZrKG5ld19rZXlfbmFtZSwgYmFzZSwgdmssIGYpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgc3Via2V5cyAqLwogICAgaWYgKG5rLT5ucl9zdWJrZXlzKSB7CiAgICAgICAgbnRfbGYgKmxmID0gKG50X2xmKikoYmFzZStuay0+bGZfb2ZmKzQpOwogICAgICAgIGlmICghX250X2R1bXBfbGYobmV3X2tleV9uYW1lLCBiYXNlLCBuay0+bnJfc3Via2V5cywgbGYsIGYsIGxldmVsLTEpKSB7CiAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyogZW5kIG50IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NldF9yZWdpc3RyeV9sZXZlbHMgW0ludGVybmFsXQogKgogKiBzZXQgbGV2ZWwgdG8gMCBmb3IgbG9hZGluZyBzeXN0ZW0gZmlsZXMKICogc2V0IGxldmVsIHRvIDEgZm9yIGxvYWRpbmcgdXNlciBmaWxlcwogKi8Kc3RhdGljIHZvaWQgX3NldF9yZWdpc3RyeV9sZXZlbHMoaW50IGxldmVsLGludCBzYXZpbmcsaW50IHBlcmlvZCkKewogICAgU0VSVkVSX1NUQVJUX1JFUSggc2V0X3JlZ2lzdHJ5X2xldmVscyApCiAgICB7CglyZXEtPmN1cnJlbnQgPSBsZXZlbDsKCXJlcS0+c2F2aW5nICA9IHNhdmluZzsKICAgICAgICByZXEtPnBlcmlvZCAgPSBwZXJpb2Q7CiAgICAgICAgU0VSVkVSX0NBTEwoKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwp9CgovKiBfc2F2ZV9hdF9leGl0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX3NhdmVfYXRfZXhpdChIS0VZIGhrZXksTFBDU1RSIHBhdGgpCnsKICAgIExQQ1NUUiBjb25mZGlyID0gZ2V0X2NvbmZpZ19kaXIoKTsKICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oY29uZmRpcikgKyBzdHJsZW4ocGF0aCkgKyAyOwoKICAgIGlmIChsZW4gPiBSRVFVRVNUX01BWF9WQVJfU0laRSkgewogICAgICAgIEVSUiggImNvbmZpZyBkaXIgJyVzJyB0b28gbG9uZ1xuIiwgY29uZmRpciApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFNFUlZFUl9TVEFSVF9WQVJfUkVRKCBzYXZlX3JlZ2lzdHJ5X2F0ZXhpdCwgbGVuICkKICAgIHsKICAgICAgICBzcHJpbnRmKCBzZXJ2ZXJfZGF0YV9wdHIocmVxKSwgIiVzLyVzIiwgY29uZmRpciwgcGF0aCApOwogICAgICAgIHJlcS0+aGtleSA9IGhrZXk7CiAgICAgICAgU0VSVkVSX0NBTEwoKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfVkFSX1JFUTsKfQoKLyogY29uZmlndXJlIHNhdmUgZmlsZXMgYW5kIHN0YXJ0IHRoZSBwZXJpb2RpYyBzYXZpbmcgdGltZXIgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfaW5pdF9yZWdpc3RyeV9zYXZpbmcoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IGFsbDsKICAgIGludCBwZXJpb2Q7CgogICAgYWxsICA9IFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiU2F2ZU9ubHlVcGRhdGVkS2V5cyIsMSk7CiAgICBwZXJpb2QgPSBQUk9GSUxFX0dldFdpbmVJbmlJbnQoInJlZ2lzdHJ5IiwiUGVyaW9kaWNTYXZlIiwwKTsKCiAgICAvKiBzZXQgc2F2aW5nIGxldmVsICgwIGZvciBzYXZpbmcgZXZlcnl0aGluZywgMSBmb3Igc2F2aW5nIG9ubHkgbW9kaWZpZWQga2V5cykgKi8KICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDEsIWFsbCxwZXJpb2QqMTAwMCk7CgogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiV3JpdGV0b0hvbWVSZWdpc3RyeUZpbGVzIiwxKSkKICAgIHsKICAgICAgICBfc2F2ZV9hdF9leGl0KEhLRVlfQ1VSUkVOVF9VU0VSLFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUiApOwogICAgICAgIF9zYXZlX2F0X2V4aXQoSEtFWV9MT0NBTF9NQUNISU5FLFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUpOwogICAgICAgIF9zYXZlX2F0X2V4aXQoaGtleV91c2Vyc19kZWZhdWx0LFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICB9Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLiAKICovCnN0YXRpYyB2b2lkIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXModm9pZCkgewoJSEtFWQloa2V5OwoJY2hhcglidWZbMjAwXTsKCglUUkFDRSgiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXlBKEhLRVlfRFlOX0RBVEEsIlBlcmZTdGF0c1xcU3RhdERhdGEiLCZoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgICAgICAvKiBUaGlzIHdhcyBhbiBPcGVuLCBidXQgc2luY2UgaXQgaXMgY2FsbGVkIGJlZm9yZSB0aGUgcmVhbCByZWdpc3RyaWVzCiAgICAgICAgICAgYXJlIGxvYWRlZCwgaXQgd2FzIGNoYW5nZWQgdG8gYSBDcmVhdGUgLSBNVEIgOTgwNTA3Ki8KCVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbSIsJmhrZXkpOwoJUmVnU2V0VmFsdWVFeEEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvd3MgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8KCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4QShoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCiAgICAgICAgUmVnQ3JlYXRlS2V5QShIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwp9CgojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgICAgMAojZGVmaW5lIFJFR19XSU45NSAgICAgMQojZGVmaW5lIFJFR19XSU5OVCAgICAgMgoKLyogcmV0dXJuIHRoZSB0eXBlIG9mIG5hdGl2ZSByZWdpc3RyeSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF9yZWdfdHlwZSh2b2lkKQp7CiAgICBjaGFyIHdpbmRpcltNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGNoYXIgdG1wW01BWF9QQVRITkFNRV9MRU5dOwogICAgaW50IHJldCA9IFJFR19XSU4zMTsKCiAgICBHZXRXaW5kb3dzRGlyZWN0b3J5QSh3aW5kaXIsTUFYX1BBVEhOQU1FX0xFTik7CgogICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0zMi9jb25maWcvc3lzdGVtIC0tPiB3aW5udCAqLwogICAgc3RyY3B5KHRtcCwgd2luZGlyKTsKICAgIHN0cm5jYXQodG1wLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzeXN0ZW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHRtcCkgLSAxKTsKICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQSh0bXApICE9IChEV09SRCktMSkgewogICAgICByZXQgPSBSRUdfV0lOTlQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbS5kYXQgLS0+IHdpbjk1ICovCiAgICAgIHN0cmNweSh0bXAsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQodG1wLCAiXFxzeXN0ZW0uZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbih0bXApIC0gMSk7CiAgICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQSh0bXApICE9IChEV09SRCktMSkgewogICAgICAgIHJldCA9IFJFR19XSU45NTsKICAgICAgfQogICAgfQoKICAgIGlmICgocmV0ID09IFJFR19XSU5OVCkgJiYgKCFQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgdG1wLCBNQVhfUEFUSE5BTUVfTEVOKSkpIHsKICAgICAgIE1FU1NBR0UoIldoZW4geW91IGFyZSBydW5uaW5nIHdpdGggYSBuYXRpdmUgTlQgZGlyZWN0b3J5IHNwZWNpZnlcbiIpOwogICAgICAgTUVTU0FHRSgiJ1Byb2ZpbGU9PHByb2ZpbGVkaXJlY3Rvcnk+JyBvciBkaXNhYmxlIGxvYWRpbmcgb2YgV2luZG93c1xuIik7CiAgICAgICBNRVNTQUdFKCJyZWdpc3RyeSAoTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzPU4pXG4iKTsKICAgICAgIHJldCA9IFJFR19ET05UTE9BRDsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgojZGVmaW5lIFdJTkVfUkVHX1ZFUl9FUlJPUiAgLTEKI2RlZmluZSBXSU5FX1JFR19WRVJfMSAgICAgICAwCiNkZWZpbmUgV0lORV9SRUdfVkVSXzIgICAgICAgMQojZGVmaW5lIFdJTkVfUkVHX1ZFUl9PTEQgICAgIDIKI2RlZmluZSBXSU5FX1JFR19WRVJfVU5LTk9XTiAzCgovKiByZXR1cm4gdGhlIHZlcnNpb24gb2Ygd2luZSByZWdpc3RyeSBmaWxlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZ2V0X3dpbmVfcmVnaXN0cnlfZmlsZV9mb3JtYXRfdmVyc2lvbihMUENTVFIgZm4pCnsKICAgIEZJTEUgKmY7CiAgICBjaGFyIHRtcFs1MF07CiAgICBpbnQgdmVyOwoKICAgIGlmICgoZj1mb3BlbihmbiwicnQiKSkgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9FUlJPUjsKICAgIH0KCiAgICBpZiAoZmdldHModG1wLDUwLGYpID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJFcnJvciByZWFkaW5nICVzOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykpOwogICAgICAgIGZjbG9zZShmKTsKICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSX0VSUk9SOwogICAgfQogICAgZmNsb3NlKGYpOwoKICAgIGlmIChzc2NhbmYodG1wLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiLCZ2ZXIpICE9IDEpIHJldHVybiBXSU5FX1JFR19WRVJfVU5LTk9XTjsKICAgIHN3aXRjaCAodmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSXzE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl8yOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gV0lORV9SRUdfVkVSX1VOS05PV047CiAgICB9Cn0KCi8qIGxvYWQgdGhlIHJlZ2lzdHJ5IGZpbGUgaW4gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBsb2FkX3dpbmVfcmVnaXN0cnkoSEtFWSBoa2V5LExQQ1NUUiBmbikKewogICAgaW50IGZpbGVfZm9ybWF0OwoKICAgIGZpbGVfZm9ybWF0ID0gX2dldF93aW5lX3JlZ2lzdHJ5X2ZpbGVfZm9ybWF0X3ZlcnNpb24oZm4pOwogICAgc3dpdGNoIChmaWxlX2Zvcm1hdCkgewoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl8xOgogICAgICAgICAgICBXQVJOKCJVbmFibGUgdG8gbG9hZCByZWdpc3RyeSBmaWxlICVzOiBvbGQgZm9ybWF0IHdoaWNoIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuXG4iLGZuKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSXzI6IHsKICAgICAgICAgICAgSEFORExFIGZpbGU7CiAgICAgICAgICAgIGlmICgoZmlsZSA9IEZJTEVfQ3JlYXRlRmlsZSggZm4sIEdFTkVSSUNfUkVBRCwgMCwgTlVMTCwgT1BFTl9FWElTVElORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgMCwgVFJVRSApKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF9yZWdpc3RyeSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5oa2V5ICAgID0gaGtleTsKICAgICAgICAgICAgICAgICAgICByZXEtPmZpbGUgICAgPSBmaWxlOwogICAgICAgICAgICAgICAgICAgIFNFUlZFUl9DQUxMKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTRVJWRVJfRU5EX1JFUTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBmaWxlICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl9VTktOT1dOOgogICAgICAgICAgICBXQVJOKCJVbmFibGUgdG8gbG9hZCByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIGZvcm1hdC5cbiIsZm4pOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfRVJST1I6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgovKiBnZW5lcmF0ZSBhbmQgcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSB0bXAgZmlsZSBhbmQgYXNzb2NpYXRlZCBzdHJlYW0gW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2dldF90bXBfZm4oRklMRSAqKmYpCnsKICAgIExQU1RSIHJldDsKICAgIGludCB0bXBfZmQsY291bnQ7CgogICAgcmV0ID0gX3htYWxsb2MoNTApOwogICAgZm9yIChjb3VudCA9IDA7OykgewogICAgICAgIHNwcmludGYocmV0LCIvdG1wL3JlZyVseCUwNHgudG1wIiwobG9uZylnZXRwaWQoKSxjb3VudCsrKTsKICAgICAgICBpZiAoKHRtcF9mZCA9IG9wZW4ocmV0LE9fQ1JFQVQgfCBPX0VYQ0wgfCBPX1dST05MWSwwNjY2KSkgIT0gLTEpIGJyZWFrOwogICAgICAgIGlmIChlcnJubyAhPSBFRVhJU1QpIHsKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgICAgICpmID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgoKmYgPSBmZG9wZW4odG1wX2ZkLCJ3IikpID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgZmRvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBjbG9zZSh0bXBfZmQpOwogICAgICAgIGZyZWUocmV0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbjk1IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1NUUiBmbixpbnQgbGV2ZWwpCnsKICAgIGludCBmZDsKICAgIEZJTEUgKmY7CiAgICBET1NfRlVMTF9OQU1FIGZ1bGxfbmFtZTsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgc3RydWN0IHN0YXQgc3Q7CgogICAgX3c5NWNyZWcgKmNyZWc7CiAgICBfdzk1cmdrbiAqcmdrbjsKICAgIF93OTVka2UgKmRrZSwgKnJvb3RfZGtlOwoKICAgIGlmICghRE9TRlNfR2V0RnVsbE5hbWUoIGZuLCAwLCAmZnVsbF9uYW1lICkpIHJldHVybiBOVUxMOwoKICAgIC8qIG1hcCB0aGUgcmVnaXN0cnkgaW50byB0aGUgbWVtb3J5ICovCiAgICBpZiAoKGZkID0gb3BlbihmdWxsX25hbWUubG9uZ19uYW1lLCBPX1JET05MWSB8IE9fTk9OQkxPQ0spKSA9PSAtMSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoKGZzdGF0KGZkLCAmc3QpID09IC0xKSkgZ290byBlcnJvcjE7CiAgICBpZiAoIXN0LnN0X3NpemUpIGdvdG8gZXJyb3IxOwogICAgaWYgKChiYXNlID0gbW1hcChOVUxMLCBzdC5zdF9zaXplLCBQUk9UX1JFQUQsIE1BUF9QUklWQVRFLCBmZCwgMCkpID09IE1BUF9GQUlMRUQpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gVzk1X1JFR19DUkVHX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLGZuKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGNyZWcgPSBiYXNlOwogICAgLyogbG9hZCB0aGUgaGVhZGVyIChyZ2tuKSAqLwogICAgcmdrbiA9IChfdzk1cmdrbiopKGNyZWcgKyAxKTsKICAgIGlmIChyZ2tuLT5pZCAhPSBXOTVfUkVHX1JHS05fSUQpIHsKICAgICAgICBFUlIoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJWx4XG4iLCByZ2tuLT5pZCk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5yb290X29mZiAhPSAweDIwKSB7CiAgICAgICAgRVJSKCJyZ2tuLT5yb290X29mZiBub3QgMHgyMCwgcGxlYXNlIHJlcG9ydCAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPmxhc3RfZGtlID4gcmdrbi0+c2l6ZSkKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGxhc3RfZGtlID4gc2l6ZSFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgLyogdmVyaWZ5IGxhc3QgZGtlICovCiAgICBka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+bGFzdF9ka2UpOwogICAgaWYgKGRrZS0+eDEgIT0gMHg4MDAwMDAwMCkKICAgIHsgLyogd3JvbmcgbWFnaWMgKi8KICAgICAgRVJSKCJsYXN0IGRrZSBpbnZhbGlkICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnNpemUgPiBjcmVnLT5yZ2RiX29mZikKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJna24gc2l6ZSA+IHJnZGJfb2ZmICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgcm9vdF9ka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+cm9vdF9vZmYpOwogICAgaWYgKCAocm9vdF9ka2UtPnByZXZsdmwgIT0gMHhmZmZmZmZmZikgfHwgKHJvb3RfZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYpICkKICAgIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgaW52YWxpZCByb290IGRrZSAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF93OTVfZHVtcF9ka2UoIiIsY3JlZyxyZ2tuLHJvb3RfZGtlLGYsbGV2ZWwpOwogICAgZmNsb3NlKGYpOwoKZXJyb3I6CiAgICBpZihyZXQgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXMuXG4iLGZuKTsKICAgICAgICBFUlIoIlBsZWFzZSByZXBvcnQgdG8gYS5tb2hyQG1haWx0by5kZS5cbiIpOwogICAgICAgIEVSUigiTWFrZSBhIGJhY2t1cCBvZiB0aGUgZmlsZSwgcnVuIGEgZ29vZCByZWcgY2xlYW5lciBwcm9ncmFtIGFuZCB0cnkgYWdhaW4hXG4iKTsKICAgIH0KCiAgICBtdW5tYXAoYmFzZSwgc3Quc3Rfc2l6ZSk7CmVycm9yMToKICAgIGNsb3NlKGZkKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2lubnQgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDU1RSIGZuLGludCBsZXZlbCkKewogICAgaW50IGZkOwogICAgRklMRSAqZjsKICAgIERPU19GVUxMX05BTUUgZnVsbF9uYW1lOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBzdHJ1Y3Qgc3RhdCBzdDsKCiAgICBudF9yZWdmICpyZWdmOwogICAgbnRfaGJpbiAqaGJpbjsKICAgIG50X2hiaW5fc3ViICpoYmluX3N1YjsKICAgIG50X25rICpuazsKCiAgICBpZiAoIURPU0ZTX0dldEZ1bGxOYW1lKCBmbiwgMCwgJmZ1bGxfbmFtZSApKSByZXR1cm4gTlVMTDsKCiAgICAvKiBtYXAgdGhlIHJlZ2lzdHJ5IGludG8gdGhlIG1lbW9yeSAqLwogICAgaWYgKChmZCA9IG9wZW4oZnVsbF9uYW1lLmxvbmdfbmFtZSwgT19SRE9OTFkgfCBPX05PTkJMT0NLKSkgPT0gLTEpIHJldHVybiBOVUxMOwogICAgaWYgKChmc3RhdChmZCwgJnN0KSA9PSAtMSkpIGdvdG8gZXJyb3IxOwogICAgaWYgKCFzdC5zdF9zaXplKSBnb3RvIGVycm9yMTsKICAgIGlmICgoYmFzZSA9IG1tYXAoTlVMTCwgc3Quc3Rfc2l6ZSwgUFJPVF9SRUFELCBNQVBfUFJJVkFURSwgZmQsIDApKSA9PSBNQVBfRkFJTEVEKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IE5UX1JFR19IRUFERVJfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW5udCByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsZm4pOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogc3RhcnQgYmxvY2sgKi8KICAgIHJlZ2YgPSBiYXNlOwoKICAgIC8qIGhiaW4gYmxvY2sgKi8KICAgIGhiaW4gPSAobnRfaGJpbiopKChjaGFyKikgYmFzZSArIDB4MTAwMCk7CiAgICBpZiAoaGJpbi0+aWQgIT0gTlRfUkVHX1BPT0xfQkxPQ0tfSUQpIHsKICAgICAgRVJSKCAiaGJpbiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBoYmluX3N1YiBibG9jayAqLwogICAgaGJpbl9zdWIgPSAobnRfaGJpbl9zdWIqKSYoaGJpbi0+aGJpbl9zdWIpOwogICAgaWYgKChoYmluX3N1Yi0+ZGF0YVswXSAhPSAnbicpIHx8IChoYmluX3N1Yi0+ZGF0YVsxXSAhPSAnaycpKSB7CiAgICAgIEVSUiggImhiaW5fc3ViIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIG5rIGJsb2NrICovCiAgICBuayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CiAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpIHsKICAgICAgRVJSKCAic3BlY2lhbCBuayBibG9jayBub3QgZm91bmRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF9udF9kdW1wX25rKCIiLChjaGFyKiliYXNlKzB4MTAwMCxuayxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgbXVubWFwKGJhc2Usc3Quc3Rfc2l6ZSk7CmVycm9yMToKICAgIGNsb3NlKGZkKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgbmF0aXZlIHJlZ2lzdHJ5IHRvIHdpbmUgZm9ybWF0IGFuZCBsb2FkIGl0IHZpYSBzZXJ2ZXIgY2FsbCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShMUENTVFIgZm4sSEtFWSBoa2V5LGludCByZWdfdHlwZSxpbnQgbGV2ZWwpCnsKICAgIExQU1RSIHRtcCA9IE5VTEw7CgogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOgogICAgICAgICAgICAvKiBGSVhNRTogZm9sbG93aW5nIGZ1bmN0aW9uIGRvZXNuJ3QgcmVhbGx5IGNvbnZlcnQgeWV0ICovCiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIEVSUigiRG9uJ3Qga25vdyBob3cgdG8gY29udmVydCBuYXRpdmUgMy4xIHJlZ2lzdHJ5IHlldC5cbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIlVua25vd24gcmVnaXN0cnkgZm9ybWF0IHBhcmFtZXRlciAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHRtcCAhPSBOVUxMKSB7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXksdG1wKTsKICAgICAgICBUUkFDRSgiRmlsZSAlcyBzdWNjZXNzZnVsbHkgY29udmVydGVkIHRvICVzIGFuZCBsb2FkZWQgdG8gcmVnaXN0cnkuXG4iLGZuLHRtcCk7CiAgICAgICAgdW5saW5rKHRtcCk7CiAgICB9CiAgICBlbHNlIFdBUk4oIlVuYWJsZSB0byBjb252ZXJ0ICVzIChkb2Vzbid0IGV4aXN0PylcbiIsZm4pOwogICAgZnJlZSh0bXApOwp9CgovKiBsb2FkIGFsbCBuYXRpdmUgd2luZG93cyByZWdpc3RyeSBmaWxlcyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX3dpbmRvd3NfcmVnaXN0cnkoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IHJlZ190eXBlOwogICAgY2hhciB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBjaGFyIHBhdGhbTUFYX1BBVEhOQU1FX0xFTl07CgogICAgR2V0V2luZG93c0RpcmVjdG9yeUEod2luZGlyLE1BWF9QQVRITkFNRV9MRU4pOwoKICAgIHJlZ190eXBlID0gX2dldF9yZWdfdHlwZSgpOwogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOiB7CiAgICAgICAgICAgIEhLRVkgaGtleTsKCiAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgbnR1c2VyLmRhdCAqLwogICAgICAgICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKSB7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxudHVzZXIuZGF0Iik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0NVUlJFTlRfVVNFUixSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXGRlZmF1bHQiKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICogRklYTUUKICAgICAgICAgICAgKiAgbWFwIEhMTVxTeXN0ZW1cQ29udHJvbFNldDAwMSB0byBITE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0CiAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU1lTVEVNIiwgJmhrZXkpKSB7CgkgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwoJICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIik7CiAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTT0ZUV0FSRSIsICZoa2V5KSkgewogICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHNvZnR3YXJlIik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzYW0iKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9MT0NBTF9NQUNISU5FLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHNlY3VyaXR5Iik7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICAvKiB0aGlzIGtleSBpcyBnZW5lcmF0ZWQgd2hlbiB0aGUgbnQtY29yZSBib290ZWQgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ2xvbmUiLCZoa2V5KSkgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeSgiYzpcXHN5c3RlbS4xc3QiLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0uZGF0Iik7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCJXaW5lIiwiUHJvZmlsZSIsIiIscGF0aCxNQVhfUEFUSE5BTUVfTEVOKSkgewoJICAgICAgICAvKiB1c2VyIHNwZWNpZmljIHVzZXIuZGF0ICovCgkgICAgICAgIHN0cm5jYXQocGF0aCwgIlxcdXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0NVUlJFTlRfVVNFUixSRUdfV0lOOTUsMSk7CgoJICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCgkgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHVzZXIuZGF0Iik7CiAgICAgICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV91c2Vyc19kZWZhdWx0LFJFR19XSU45NSwxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFx1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTjk1LDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgLyogRklYTUU6IGhlcmUgd2Ugc2hvdWxkIGNvbnZlcnQgdG8gKi5yZWcgZmlsZSBzdXBwb3J0ZWQgYnkgc2VydmVyIGFuZCBjYWxsIFJFUV9MT0FEX1JFR0lTVFJZLCBzZWUgUkVHX1dJTjk1IGNhc2UgKi8KICAgICAgICAgICAgX3czMV9sb2FkcmVnKCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFJFR19ET05UTE9BRDoKICAgICAgICAgICAgVFJBQ0UoIlJFR19ET05UTE9BRFxuIik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoInN3aXRjaDogbm8gbWF0Y2ggKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgIH0KfQoKLyogbG9hZCBnbG9iYWwgcmVnaXN0cnkgZmlsZXMgKHN0b3JlZCBpbiAvZXRjL3dpbmUpIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfZ2xvYmFsX3JlZ2lzdHJ5KHZvaWQpCnsKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIC8qIExvYWQgdGhlIGdsb2JhbCBIS1UgaGl2ZSBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgIGxvYWRfd2luZV9yZWdpc3RyeSggSEtFWV9VU0VSUywgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCApOwoKICAgIC8qIExvYWQgdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KCBIS0VZX0xPQ0FMX01BQ0hJTkUsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FICk7Cn0KCi8qIGxvYWQgaG9tZSByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIH4vLndpbmUpIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfaG9tZV9yZWdpc3RyeSggSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBMUENTVFIgY29uZmRpciA9IGdldF9jb25maWdfZGlyKCk7CiAgICBMUFNUUiB0bXAgPSBfeG1hbGxvYyhzdHJsZW4oY29uZmRpcikrMjApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXlfdXNlcnNfZGVmYXVsdCx0bXApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVlfQ1VSUkVOVF9VU0VSLHRtcCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVlfTE9DQUxfTUFDSElORSx0bXApOwoKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgcmVnaXN0cnkgKG5hdGl2ZSBhbmQgZ2xvYmFsIGFuZCBob21lKSAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICAgIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0OwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGlmICghQ0xJRU5UX0lzQm9vdFRocmVhZCgpKSByZXR1cm47ICAvKiBhbHJlYWR5IGxvYWRlZCAqLwoKICAgIGlmIChSZWdDcmVhdGVLZXlBKEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleV91c2Vyc19kZWZhdWx0KSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgSEtFWV9VU0VSUy8uRGVmYXVsdFxuIiApOwogICAgICAgIEV4aXRQcm9jZXNzKDEpOwogICAgfQoKICAgIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMoKTsKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDAsMCwwKTsKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJSZWdpc3RyeSIsIkxvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcyIsMSkpCiAgICAgICAgX2xvYWRfd2luZG93c19yZWdpc3RyeSggaGtleV91c2Vyc19kZWZhdWx0ICk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkR2xvYmFsUmVnaXN0cnlGaWxlcyIsMSkpCiAgICAgICAgX2xvYWRfZ2xvYmFsX3JlZ2lzdHJ5KCk7CiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLDAsMCk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkSG9tZVJlZ2lzdHJ5RmlsZXMiLDEpKQogICAgICAgIF9sb2FkX2hvbWVfcmVnaXN0cnkoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwogICAgX2luaXRfcmVnaXN0cnlfc2F2aW5nKCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICAgIFJlZ0Nsb3NlS2V5KGhrZXlfdXNlcnNfZGVmYXVsdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICBBUEkgRlVOQ1RJT05TICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtBRFZBUEkzMi5AXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleUEgW0FEVkFQSTMyLkBdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX2EobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5VyBbQURWQVBJMzIuQF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIigleCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5QSBbQURWQVBJMzIuQF0KICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMUFdTVFIgbHBGaWxlVyA9IEhFQVBfc3RyZHVwQXRvVyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBGaWxlICk7CiAgICBMT05HIHJldCA9IFJlZ1Jlc3RvcmVLZXlXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBGaWxlVyApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleUEgW0FEVkFQSTMyLkBdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBGSVhNRSgiKCV4LCVzLCVzLCVzKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfYShscFN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl9hKGxwTmV3RmlsZSksZGVidWdzdHJfYShscE9sZEZpbGUpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKCgoKCi8qIDE2LWJpdCBmdW5jdGlvbnMgKi8KCi8qIDAgYW5kIDEgYXJlIHZhbGlkIHJvb3RrZXlzIGluIHdpbjE2IHNoZWxsLmRsbCBhbmQgYXJlIHVzZWQgYnkKICogc29tZSBwcm9ncmFtcy4gRG8gbm90IHJlbW92ZSB0aG9zZSBjYXNlcy4gLU1NCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZml4X3dpbjE2X2hrZXkoIEhLRVkgKmhrZXkgKQp7CiAgICBpZiAoKmhrZXkgPT0gMCB8fCAqaGtleSA9PSAxKSAqaGtleSA9IEhLRVlfQ0xBU1NFU19ST09UOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdFbnVtS2V5ICAgW0tFUk5FTC4yMTZdCiAqICAgICAgICAgICBSZWdFbnVtS2V5ICAgW1NIRUxMLjddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGluZGV4LCBMUFNUUiBuYW1lLCBEV09SRCBuYW1lX2xlbiApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0VudW1LZXlBKCBoa2V5LCBpbmRleCwgbmFtZSwgbmFtZV9sZW4gKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnT3BlbktleSAgIFtLRVJORUwuMjE3XQogKiAgICAgICAgICAgUmVnT3BlbktleSAgIFtTSEVMTC4xXQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBIS0VZIHJldGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ09wZW5LZXlBKCBoa2V5LCBuYW1lLCByZXRrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnQ3JlYXRlS2V5ICAgW0tFUk5FTC4yMThdCiAqICAgICAgICAgICBSZWdDcmVhdGVLZXkgICBbU0hFTEwuMl0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBIS0VZIHJldGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0NyZWF0ZUtleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVLZXkgICBbS0VSTkVMLjIxOV0KICogICAgICAgICAgIFJlZ0RlbGV0ZUtleSAgIFtTSEVMTC40XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDbG9zZUtleSAgIFtLRVJORUwuMjIwXQogKiAgICAgICAgICAgUmVnQ2xvc2VLZXkgICBbU0hFTEwuM10KICovCkRXT1JEIFdJTkFQSSBSZWdDbG9zZUtleTE2KCBIS0VZIGhrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdDbG9zZUtleSggaGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZSAgIFtLRVJORUwuMjIxXQogKiAgICAgICAgICAgUmVnU2V0VmFsdWUgICBbU0hFTEwuNV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBEV09SRCB0eXBlLCBMUENTVFIgZGF0YSwgRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUEoIGhrZXksIG5hbWUsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZVZhbHVlICBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bVZhbHVlICAgW0tFUk5FTC4yMjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIHZhbHVlLCBMUERXT1JEIHZhbF9jb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bVZhbHVlQSggaGtleSwgaW5kZXgsIHZhbHVlLCB2YWxfY291bnQsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlICAgW0tFUk5FTC4yMjRdCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlICAgW1NIRUxMLjZdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBTVFIgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgaWYgKGNvdW50KSAqY291bnQgJj0gMHhmZmZmOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVBKCBoa2V5LCBuYW1lLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlRXggICBbS0VSTkVMLjIyNV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBEV09SRCByZXNlcnZlZCwgTFBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUV4QSggaGtleSwgbmFtZSwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlRXggICBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHJlc2VydmVkLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBCWVRFICpkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgaWYgKCFjb3VudCAmJiAodHlwZT09UkVHX1NaKSkgY291bnQgPSBzdHJsZW4oZGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdGbHVzaEtleSAgIFtLRVJORUwuMjI3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0ZsdXNoS2V5KCBoa2V5ICk7Cn0K