LyoKICogIENvcHlyaWdodCAoQykgMjAwNCBieSBKYW4tQmVuZWRpY3QgR2xhdyA8amJnbGF3QGx1Zy1vd2wuZGU+CiAqLwoKLyoKICogTEsga2V5Ym9hcmQgZHJpdmVyIGZvciBMaW51eCwgYmFzZWQgb24gc3Vua2JkLmMgKEMpIGJ5IFZvanRlY2ggUGF2bGlrCiAqLwoKLyoKICogREVDIExLMjAxIGFuZCBMSzQwMSBrZXlib2FyZCBkcml2ZXIgZm9yIExpbnV4IChwcmltYXJ5IGZvciBERUNzdGF0aW9ucwogKiBhbmQgVkFYc3RhdGlvbnMsIGJ1dCBjYW4gYWxzbyBiZSB1c2VkIG9uIGFueSBzdGFuZGFyZCBSUzIzMiB3aXRoIGFuCiAqIGFkYXB0b3IpLgogKgogKiBESVNDTEFJTUVSOiBUaGlzIHdvcmtzIGZvciBfbWVfLiBJZiB5b3UgYnJlYWsgYW55dGhpbmcgYnkgdXNpbmcgdGhlCiAqIGluZm9ybWF0aW9uIGdpdmVuIGJlbG93LCBJIHdpbGwgX25vdF8gYmUgbGlhYmxlIQogKgogKiBSSjExIHBpbm91dDoJCVRvIERFOToJCU9yIERCMjU6CiAqIAkxIC0gUnhEIDwtLS0tPglQaW4gMyAoVHhEKSA8LT4JUGluIDIgKFR4RCkKICogCTIgLSBHTkQgPC0tLS0+CVBpbiA1IChHTkQpIDwtPglQaW4gNyAoR05EKQogKiAJNCAtIFR4RCA8LS0tLT4JUGluIDIgKFJ4RCkgPC0+CVBpbiAzIChSeEQpCiAqIAkzIC0gKzEyViAoZnJvbSBIREQgZHJpdmUgY29ubmVjdG9yKSwgRE9OJ1QgY29ubmVjdCB0byBERTkgb3IgREIyNSEhIQogKgogKiBQaW4gbnVtYmVycyBmb3IgREU5IGFuZCBEQjI1IGFyZSBub3RlZCBvbiB0aGUgcGx1ZyAocXVpdGUgc21hbGw6KS4gRm9yCiAqIFJKMTEsIGl0J3MgbGlrZSB0aGlzOgogKgogKiAgICAgIF9fPV9fCUhvbGQgdGhlIHBsdWcgaW4gZnJvbnQgb2YgeW91LCBjYWJsZSBkb3dud2FyZHMsCiAqICAgICAvX19fL3wJbm9zZSBpcyBoaWRkZW4gYmVoaW5kIHRoZSBwbHVnLiBOb3csIHBpbiAxIGlzIGF0CiAqICAgIHwxMjM0fHwJdGhlIGxlZnQgc2lkZSwgcGluIDQgYXQgdGhlIHJpZ2h0IGFuZCAyIGFuZCAzIGFyZQogKiAgICB8SUlJSXx8CWluIGJldHdlZW4sIG9mIGNvdXJzZTopCiAqICAgIHwgICAgfHwKICogICAgfF9fX198LwogKiAgICAgIHx8CVNvIHRoZSBhZGFwdG9yIGNvbnNpc3RzIG9mIHRocmVlIGNvbm5lY3RlZCBjYWJsZXMKICogICAgICB8fAlmb3IgZGF0YSB0cmFuc21pc3Npb24gKFJ4RCBhbmQgVHhEKSBhbmQgc2lnbmFsIGdyb3VuZC4KICoJCUFkZGl0aW9uYWxseSwgeW91IGhhdmUgdG8gZ2V0ICsxMlYgZnJvbSBzb21ld2hlcmUuCiAqIE1vc3QgZWFzaWx5LCB5b3UnbGwgZ2V0IHRoYXQgZnJvbSBhIGZsb3BweSBvciBIREQgcG93ZXIgY29ubmVjdG9yLgogKiBJdCdzIHRoZSB5ZWxsb3cgY2FibGUgdGhlcmUgKGJsYWNrIGlzIGdyb3VuZCBhbmQgcmVkIGlzICs1VikuCiAqCiAqIFRoZSBrZXlib2FyZCBhbmQgYWxsIHRoZSBjb21tYW5kcyBpdCB1bmRlcnN0YW5kcyBhcmUgZG9jdW1lbnRlZCBpbgogKiAiVkNCMDIgVmlkZW8gU3Vic3lzdGVtIC0gVGVjaG5pY2FsIE1hbnVhbCIsIEVLLTEwNEFBLVRNLTAwMS4gVGhpcwogKiBkb2N1bWVudCBpcyBMSzIwMSBzcGVjaWZpYywgYnV0IExLNDAxIGlzIG1vc3RseSBjb21wYXRpYmxlLiBJdCBjb21lcwogKiB1cCBpbiBMSzIwMSBtb2RlIGFuZCBkb2Vzbid0IHJlcG9ydCBhbnkgb2YgdGhlIGFkZGl0aW9uYWwga2V5cyBpdAogKiBoYXMuIFRoZXNlIG5lZWQgdG8gYmUgc3dpdGNoZWQgb24gd2l0aCB0aGUgTEtfQ01EX0VOQUJMRV9MSzQwMQogKiBjb21tYW5kLiBZb3UnbGwgZmluZCB0aGlzIGRvY3VtZW50IChzY2FubmVkIC5wZGYgZmlsZSkgb24gTUFOWCwKICogYSBzZWFyY2ggZW5naW5lIHNwZWNpZmljIHRvIERFQyBkb2N1bWVudGF0aW9uLiBUcnkKICogaHR0cDovL3d3dy52dDEwMC5uZXQvbWFueC9kZXRhaWxzP3BuPUVLLTEwNEFBLVRNLTAwMTtpZD0yMTtjcD0xCiAqLwoKLyoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICoKICogU2hvdWxkIHlvdSBuZWVkIHRvIGNvbnRhY3QgbWUsIHRoZSBhdXRob3IsIHlvdSBjYW4gZG8gc28gZWl0aGVyIGJ5CiAqIGVtYWlsIG9yIGJ5IHBhcGVyIG1haWw6CiAqIEphbi1CZW5lZGljdCBHbGF3LCBMaWxpZW5zdHJh32UgMTYsIDMzNzkwIEj2cnN0ZSAobmVhciBIYWxsZS9XZXN0Zi4pLAogKiBHZXJtYW55LgogKi8KCiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGVwYXJhbS5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbnB1dC5oPgojaW5jbHVkZSA8bGludXgvc2VyaW8uaD4KI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgoKI2RlZmluZSBEUklWRVJfREVTQwkiTEsga2V5Ym9hcmQgZHJpdmVyIgoKTU9EVUxFX0FVVEhPUiAoIkphbi1CZW5lZGljdCBHbGF3IDxqYmdsYXdAbHVnLW93bC5kZT4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OIChEUklWRVJfREVTQyk7Ck1PRFVMRV9MSUNFTlNFICgiR1BMIik7CgovKgogKiBLbm93biBwYXJhbWV0ZXJzOgogKgliZWxsX3ZvbHVtZQogKglrZXljbGlja192b2x1bWUKICoJY3RybGNsaWNrX3ZvbHVtZQogKgogKiBQbGVhc2Ugbm90aWNlIHRoYXQgdGhlcmUncyBub3QgeWV0IGFuIEFQSSB0byBzZXQgdGhlc2UgYXQgcnVudGltZS4KICovCnN0YXRpYyBpbnQgYmVsbF92b2x1bWUgPSAxMDA7IC8qICUgKi8KbW9kdWxlX3BhcmFtIChiZWxsX3ZvbHVtZSwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyAoYmVsbF92b2x1bWUsICJCZWxsIHZvbHVtZSAoaW4gJSkuIGRlZmF1bHQgaXMgMTAwJSIpOwoKc3RhdGljIGludCBrZXljbGlja192b2x1bWUgPSAxMDA7IC8qICUgKi8KbW9kdWxlX3BhcmFtIChrZXljbGlja192b2x1bWUsIGludCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MgKGtleWNsaWNrX3ZvbHVtZSwgIktleWNsaWNrIHZvbHVtZSAoaW4gJSksIGRlZmF1bHQgaXMgMTAwJSIpOwoKc3RhdGljIGludCBjdHJsY2xpY2tfdm9sdW1lID0gMTAwOyAvKiAlICovCm1vZHVsZV9wYXJhbSAoY3RybGNsaWNrX3ZvbHVtZSwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyAoY3RybGNsaWNrX3ZvbHVtZSwgIkN0cmxjbGljayB2b2x1bWUgKGluICUpLCBkZWZhdWx0IGlzIDEwMCUiKTsKCnN0YXRpYyBpbnQgbGsyMDFfY29tcG9zZV9pc19hbHQgPSAwOwptb2R1bGVfcGFyYW0gKGxrMjAxX2NvbXBvc2VfaXNfYWx0LCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDIChsazIwMV9jb21wb3NlX2lzX2FsdCwgIklmIHNldCBub24temVybywgTEsyMDEnIENvbXBvc2Uga2V5ICIKCQkid2lsbCBhY3QgYXMgYW4gQWx0IGtleSIpOwoKCgojdW5kZWYgTEtLQkRfREVCVUcKI2lmZGVmIExLS0JEX0RFQlVHCiNkZWZpbmUgREJHKHguLi4pIHByaW50ayAoeCkKI2Vsc2UKI2RlZmluZSBEQkcoeC4uLikgZG8ge30gd2hpbGUgKDApCiNlbmRpZgoKLyogTEVEIGNvbnRyb2wgKi8KI2RlZmluZSBMS19MRURfV0FJVAkJMHg4MQojZGVmaW5lIExLX0xFRF9DT01QT1NFCQkweDgyCiNkZWZpbmUgTEtfTEVEX1NISUZUTE9DSwkweDg0CiNkZWZpbmUgTEtfTEVEX1NDUk9MTExPQ0sJMHg4OAojZGVmaW5lIExLX0NNRF9MRURfT04JCTB4MTMKI2RlZmluZSBMS19DTURfTEVEX09GRgkJMHgxMQoKLyogTW9kZSBjb250cm9sICovCiNkZWZpbmUgTEtfTU9ERV9ET1dOCQkweDgwCiNkZWZpbmUgTEtfTU9ERV9BVVRPRE9XTgkweDgyCiNkZWZpbmUgTEtfTU9ERV9VUERPV04JCTB4ODYKI2RlZmluZSBMS19DTURfU0VUX01PREUobW9kZSxkaXYpCSgobW9kZSkgfCAoKGRpdikgPDwgMykpCgovKiBNaXNjIGNvbW1hbmRzICovCiNkZWZpbmUgTEtfQ01EX0VOQUJMRV9LRVlDTElDSwkweDFiCiNkZWZpbmUgTEtfQ01EX0RJU0FCTEVfS0VZQ0xJQ0sJMHg5OQojZGVmaW5lIExLX0NNRF9ESVNBQkxFX0JFTEwJMHhhMQojZGVmaW5lIExLX0NNRF9TT1VORF9CRUxMCTB4YTcKI2RlZmluZSBMS19DTURfRU5BQkxFX0JFTEwJMHgyMwojZGVmaW5lIExLX0NNRF9ESVNBQkxFX0NUUkNMSUNLCTB4YjkKI2RlZmluZSBMS19DTURfRU5BQkxFX0NUUkNMSUNLCTB4YmIKI2RlZmluZSBMS19DTURfU0VUX0RFRkFVTFRTCTB4ZDMKI2RlZmluZSBMS19DTURfUE9XRVJDWUNMRV9SRVNFVAkweGZkCiNkZWZpbmUgTEtfQ01EX0VOQUJMRV9MSzQwMQkweGU5CiNkZWZpbmUgTEtfQ01EX1JFUVVFU1RfSUQJMHhhYgoKLyogTWlzYyByZXNwb25zZXMgZnJvbSBrZXlib2FyZCAqLwojZGVmaW5lIExLX1NUVUNLX0tFWQkJMHgzZAojZGVmaW5lIExLX1NFTEZURVNUX0ZBSUxFRAkweDNlCiNkZWZpbmUgTEtfQUxMX0tFWVNfVVAJCTB4YjMKI2RlZmluZSBMS19NRVRST05PTUUJCTB4YjQKI2RlZmluZSBMS19PVVRQVVRfRVJST1IJCTB4YjUKI2RlZmluZSBMS19JTlBVVF9FUlJPUgkJMHhiNgojZGVmaW5lIExLX0tCRF9MT0NLRUQJCTB4YjcKI2RlZmluZSBMS19LQkRfVEVTVF9NT0RFX0FDSwkweGI4CiNkZWZpbmUgTEtfUFJFRklYX0tFWV9ET1dOCTB4YjkKI2RlZmluZSBMS19NT0RFX0NIQU5HRV9BQ0sJMHhiYQojZGVmaW5lIExLX1JFU1BPTlNFX1JFU0VSVkVECTB4YmIKCiNkZWZpbmUgTEtfTlVNX0tFWUNPREVTCQkyNTYKI2RlZmluZSBMS19OVU1fSUdOT1JFX0JZVEVTCTYKdHlwZWRlZiB1X2ludDE2X3QgbGtfa2V5Y29kZV90OwoKCgpzdGF0aWMgbGtfa2V5Y29kZV90IGxra2JkX2tleWNvZGVbTEtfTlVNX0tFWUNPREVTXSA9IHsKCVsweDU2XSA9IEtFWV9GMSwKCVsweDU3XSA9IEtFWV9GMiwKCVsweDU4XSA9IEtFWV9GMywKCVsweDU5XSA9IEtFWV9GNCwKCVsweDVhXSA9IEtFWV9GNSwKCVsweDY0XSA9IEtFWV9GNiwKCVsweDY1XSA9IEtFWV9GNywKCVsweDY2XSA9IEtFWV9GOCwKCVsweDY3XSA9IEtFWV9GOSwKCVsweDY4XSA9IEtFWV9GMTAsCglbMHg3MV0gPSBLRVlfRjExLAoJWzB4NzJdID0gS0VZX0YxMiwKCVsweDczXSA9IEtFWV9GMTMsCglbMHg3NF0gPSBLRVlfRjE0LAoJWzB4N2NdID0gS0VZX0YxNSwKCVsweDdkXSA9IEtFWV9GMTYsCglbMHg4MF0gPSBLRVlfRjE3LAoJWzB4ODFdID0gS0VZX0YxOCwKCVsweDgyXSA9IEtFWV9GMTksCglbMHg4M10gPSBLRVlfRjIwLAoJWzB4OGFdID0gS0VZX0ZJTkQsCglbMHg4Yl0gPSBLRVlfSU5TRVJULAoJWzB4OGNdID0gS0VZX0RFTEVURSwKCVsweDhkXSA9IEtFWV9TRUxFQ1QsCglbMHg4ZV0gPSBLRVlfUEFHRVVQLAoJWzB4OGZdID0gS0VZX1BBR0VET1dOLAoJWzB4OTJdID0gS0VZX0tQMCwKCVsweDk0XSA9IEtFWV9LUERPVCwKCVsweDk1XSA9IEtFWV9LUEVOVEVSLAoJWzB4OTZdID0gS0VZX0tQMSwKCVsweDk3XSA9IEtFWV9LUDIsCglbMHg5OF0gPSBLRVlfS1AzLAoJWzB4OTldID0gS0VZX0tQNCwKCVsweDlhXSA9IEtFWV9LUDUsCglbMHg5Yl0gPSBLRVlfS1A2LAoJWzB4OWNdID0gS0VZX0tQQ09NTUEsCglbMHg5ZF0gPSBLRVlfS1A3LAoJWzB4OWVdID0gS0VZX0tQOCwKCVsweDlmXSA9IEtFWV9LUDksCglbMHhhMF0gPSBLRVlfS1BNSU5VUywKCVsweGExXSA9IEtFWV9QUk9HMSwKCVsweGEyXSA9IEtFWV9QUk9HMiwKCVsweGEzXSA9IEtFWV9QUk9HMywKCVsweGE0XSA9IEtFWV9QUk9HNCwKCVsweGE3XSA9IEtFWV9MRUZULAoJWzB4YThdID0gS0VZX1JJR0hULAoJWzB4YTldID0gS0VZX0RPV04sCglbMHhhYV0gPSBLRVlfVVAsCglbMHhhYl0gPSBLRVlfUklHSFRTSElGVCwKCVsweGFjXSA9IEtFWV9MRUZUQUxULAoJWzB4YWRdID0gS0VZX0NPTVBPU0UsIC8qIFJpZ2h0IENvbXBvc2UsIHRoYXQgaXMuICovCglbMHhhZV0gPSBLRVlfTEVGVFNISUZULCAvKiBTYW1lIGFzIEtFWV9SSUdIVFNISUZUIG9uIExLMjAxICovCglbMHhhZl0gPSBLRVlfTEVGVENUUkwsCglbMHhiMF0gPSBLRVlfQ0FQU0xPQ0ssCglbMHhiMV0gPSBLRVlfQ09NUE9TRSwgLyogTGVmdCBDb21wb3NlLCB0aGF0IGlzLiAqLwoJWzB4YjJdID0gS0VZX1JJR0hUQUxULAoJWzB4YmNdID0gS0VZX0JBQ0tTUEFDRSwKCVsweGJkXSA9IEtFWV9FTlRFUiwKCVsweGJlXSA9IEtFWV9UQUIsCglbMHhiZl0gPSBLRVlfRVNDLAoJWzB4YzBdID0gS0VZXzEsCglbMHhjMV0gPSBLRVlfUSwKCVsweGMyXSA9IEtFWV9BLAoJWzB4YzNdID0gS0VZX1osCglbMHhjNV0gPSBLRVlfMiwKCVsweGM2XSA9IEtFWV9XLAoJWzB4YzddID0gS0VZX1MsCglbMHhjOF0gPSBLRVlfWCwKCVsweGM5XSA9IEtFWV8xMDJORCwKCVsweGNiXSA9IEtFWV8zLAoJWzB4Y2NdID0gS0VZX0UsCglbMHhjZF0gPSBLRVlfRCwKCVsweGNlXSA9IEtFWV9DLAoJWzB4ZDBdID0gS0VZXzQsCglbMHhkMV0gPSBLRVlfUiwKCVsweGQyXSA9IEtFWV9GLAoJWzB4ZDNdID0gS0VZX1YsCglbMHhkNF0gPSBLRVlfU1BBQ0UsCglbMHhkNl0gPSBLRVlfNSwKCVsweGQ3XSA9IEtFWV9ULAoJWzB4ZDhdID0gS0VZX0csCglbMHhkOV0gPSBLRVlfQiwKCVsweGRiXSA9IEtFWV82LAoJWzB4ZGNdID0gS0VZX1ksCglbMHhkZF0gPSBLRVlfSCwKCVsweGRlXSA9IEtFWV9OLAoJWzB4ZTBdID0gS0VZXzcsCglbMHhlMV0gPSBLRVlfVSwKCVsweGUyXSA9IEtFWV9KLAoJWzB4ZTNdID0gS0VZX00sCglbMHhlNV0gPSBLRVlfOCwKCVsweGU2XSA9IEtFWV9JLAoJWzB4ZTddID0gS0VZX0ssCglbMHhlOF0gPSBLRVlfQ09NTUEsCglbMHhlYV0gPSBLRVlfOSwKCVsweGViXSA9IEtFWV9PLAoJWzB4ZWNdID0gS0VZX0wsCglbMHhlZF0gPSBLRVlfRE9ULAoJWzB4ZWZdID0gS0VZXzAsCglbMHhmMF0gPSBLRVlfUCwKCVsweGYyXSA9IEtFWV9TRU1JQ09MT04sCglbMHhmM10gPSBLRVlfU0xBU0gsCglbMHhmNV0gPSBLRVlfRVFVQUwsCglbMHhmNl0gPSBLRVlfUklHSFRCUkFDRSwKCVsweGY3XSA9IEtFWV9CQUNLU0xBU0gsCglbMHhmOV0gPSBLRVlfTUlOVVMsCglbMHhmYV0gPSBLRVlfTEVGVEJSQUNFLAoJWzB4ZmJdID0gS0VZX0FQT1NUUk9QSEUsCn07CgojZGVmaW5lIENIRUNLX0xFRChMRUQsIEJJVFMpIGRvIHsJCVwKCWlmICh0ZXN0X2JpdCAoTEVELCBsay0+ZGV2LmxlZCkpCVwKCQlsZWRzX29uIHw9IEJJVFM7CQlcCgllbHNlCQkJCQlcCgkJbGVkc19vZmYgfD0gQklUUzsJCVwKCX0gd2hpbGUgKDApCgovKgogKiBQZXIta2V5Ym9hcmQgZGF0YQogKi8Kc3RydWN0IGxra2JkIHsKCWxrX2tleWNvZGVfdCBrZXljb2RlW0xLX05VTV9LRVlDT0RFU107CglpbnQgaWdub3JlX2J5dGVzOwoJdW5zaWduZWQgY2hhciBpZFtMS19OVU1fSUdOT1JFX0JZVEVTXTsKCXN0cnVjdCBpbnB1dF9kZXYgZGV2OwoJc3RydWN0IHNlcmlvICpzZXJpbzsKCXN0cnVjdCB3b3JrX3N0cnVjdCB0cTsKCWNoYXIgbmFtZVs2NF07CgljaGFyIHBoeXNbMzJdOwoJY2hhciB0eXBlOwoJaW50IGJlbGxfdm9sdW1lOwoJaW50IGtleWNsaWNrX3ZvbHVtZTsKCWludCBjdHJsY2xpY2tfdm9sdW1lOwp9OwoKLyoKICogQ2FsY3VsYXRlIHZvbHVtZSBwYXJhbWV0ZXIgYnl0ZSBmb3IgYSBnaXZlbiB2b2x1bWUuCiAqLwpzdGF0aWMgdW5zaWduZWQgY2hhcgp2b2x1bWVfdG9faHcgKGludCB2b2x1bWVfcGVyY2VudCkKewoJdW5zaWduZWQgY2hhciByZXQgPSAwOwoKCWlmICh2b2x1bWVfcGVyY2VudCA8IDApCgkJdm9sdW1lX3BlcmNlbnQgPSAwOwoJaWYgKHZvbHVtZV9wZXJjZW50ID4gMTAwKQoJCXZvbHVtZV9wZXJjZW50ID0gMTAwOwoKCWlmICh2b2x1bWVfcGVyY2VudCA+PSAwKQoJCXJldCA9IDc7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gMTMpCS8qIDEyLjUgKi8KCQlyZXQgPSA2OwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDI1KQoJCXJldCA9IDU7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gMzgpCS8qIDM3LjUgKi8KCQlyZXQgPSA0OwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDUwKQoJCXJldCA9IDM7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gNjMpCS8qIDYyLjUgKi8KCQlyZXQgPSAyOwkJLyogVGhpcyBpcyB0aGUgZGVmYXVsdCB2b2x1bWUgKi8KCWlmICh2b2x1bWVfcGVyY2VudCA+PSA3NSkKCQlyZXQgPSAxOwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDg4KQkvKiA4Ny41ICovCgkJcmV0ID0gMDsKCglyZXQgfD0gMHg4MDsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZApsa2tiZF9kZXRlY3Rpb25fZG9uZSAoc3RydWN0IGxra2JkICpsaykKewoJaW50IGk7CgoJLyoKCSAqIFJlc2V0IHNldHRpbmcgZm9yIENvbXBvc2Uga2V5LiBMZXQgQ29tcG9zZSBiZSBLRVlfQ09NUE9TRS4KCSAqLwoJbGstPmtleWNvZGVbMHhiMV0gPSBLRVlfQ09NUE9TRTsKCgkvKgoJICogUHJpbnQga2V5Ym9hcmQgbmFtZSBhbmQgbW9kaWZ5IENvbXBvc2U9QWx0IG9uIHVzZXIncyByZXF1ZXN0LgoJICovCglzd2l0Y2ggKGxrLT5pZFs0XSkgewoJCWNhc2UgMToKCQkJc3ByaW50ZiAobGstPm5hbWUsICJERUMgTEsyMDEga2V5Ym9hcmQiKTsKCgkJCWlmIChsazIwMV9jb21wb3NlX2lzX2FsdCkKCQkJCWxrLT5rZXljb2RlWzB4YjFdID0gS0VZX0xFRlRBTFQ7CgkJCWJyZWFrOwoKCQljYXNlIDI6CgkJCXNwcmludGYgKGxrLT5uYW1lLCAiREVDIExLNDAxIGtleWJvYXJkIik7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlzcHJpbnRmIChsay0+bmFtZSwgIlVua25vd24gREVDIGtleWJvYXJkIik7CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBrZXlib2FyZCBvbiAlcyBpcyB1bmtub3duLCAiCgkJCQkJInBsZWFzZSByZXBvcnQgdG8gSmFuLUJlbmVkaWN0IEdsYXcgIgoJCQkJCSI8amJnbGF3QGx1Zy1vd2wuZGU+XG4iLCBsay0+cGh5cyk7CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBrZXlib2FyZCBJRCdlZCBhczoiKTsKCQkJZm9yIChpID0gMDsgaSA8IExLX05VTV9JR05PUkVfQllURVM7IGkrKykKCQkJCXByaW50ayAoIiAweCUwMngiLCBsay0+aWRbaV0pOwoJCQlwcmludGsgKCJcbiIpOwoJCQlicmVhazsKCX0KCXByaW50ayAoS0VSTl9JTkZPICJsa2tiZDoga2V5Ym9hcmQgb24gJXMgaWRlbnRpZmllZCBhczogJXNcbiIsCgkJCWxrLT5waHlzLCBsay0+bmFtZSk7CgoJLyoKCSAqIFJlcG9ydCBlcnJvcnMgZHVyaW5nIGtleWJvYXJkIGJvb3QtdXAuCgkgKi8KCXN3aXRjaCAobGstPmlkWzJdKSB7CgkJY2FzZSAweDAwOgoJCQkvKiBBbGwgb2theSAqLwoJCQlicmVhazsKCgkJY2FzZSBMS19TVFVDS19LRVk6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBTdHVjayBrZXkgb24ga2V5Ym9hcmQgYXQgIgoJCQkJCSIlc1xuIiwgbGstPnBoeXMpOwoJCQlicmVhazsKCgkJY2FzZSBMS19TRUxGVEVTVF9GQUlMRUQ6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBTZWxmdGVzdCBmYWlsZWQgb24ga2V5Ym9hcmQgIgoJCQkJCSJhdCAlcywga2V5Ym9hcmQgbWF5IG5vdCB3b3JrICIKCQkJCQkicHJvcGVybHlcbiIsIGxrLT5waHlzKTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBVbmtub3duIGVycm9yICUwMnggb24gIgoJCQkJCSJrZXlib2FyZCBhdCAlc1xuIiwgbGstPmlkWzJdLAoJCQkJCWxrLT5waHlzKTsKCQkJYnJlYWs7Cgl9CgoJLyoKCSAqIFRyeSB0byBoaW50IHVzZXIgaWYgdGhlcmUncyBhIHN0dWNrIGtleS4KCSAqLwoJaWYgKGxrLT5pZFsyXSA9PSBMS19TVFVDS19LRVkgJiYgbGstPmlkWzNdICE9IDApCgkJcHJpbnRrIChLRVJOX0VSUiAiU2NhbmNvZGUgb2Ygc3R1Y2sga2V5IGlzIDB4JTAyeCwga2V5Y29kZSAiCgkJCQkiaXMgMHglMDR4XG4iLCBsay0+aWRbM10sCgkJCQlsay0+a2V5Y29kZVtsay0+aWRbM11dKTsKCglyZXR1cm47Cn0KCi8qCiAqIGxra2JkX2ludGVycnVwdCgpIGlzIGNhbGxlZCBieSB0aGUgbG93IGxldmVsIGRyaXZlciB3aGVuIGEgY2hhcmFjdGVyCiAqIGlzIHJlY2VpdmVkLgogKi8Kc3RhdGljIGlycXJldHVybl90Cmxra2JkX2ludGVycnVwdCAoc3RydWN0IHNlcmlvICpzZXJpbywgdW5zaWduZWQgY2hhciBkYXRhLCB1bnNpZ25lZCBpbnQgZmxhZ3MsCgkJc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBsa2tiZCAqbGsgPSBzZXJpby0+cHJpdmF0ZTsKCWludCBpOwoKCURCRyAoS0VSTl9JTkZPICJHb3QgYnl0ZSAweCUwMnhcbiIsIGRhdGEpOwoKCWlmIChsay0+aWdub3JlX2J5dGVzID4gMCkgewoJCURCRyAoS0VSTl9JTkZPICJJZ25vcmluZyBhIGJ5dGUgb24gJXNcbiIsCgkJCQlsay0+bmFtZSk7CgkJbGstPmlkW0xLX05VTV9JR05PUkVfQllURVMgLSBsay0+aWdub3JlX2J5dGVzLS1dID0gZGF0YTsKCgkJaWYgKGxrLT5pZ25vcmVfYnl0ZXMgPT0gMCkKCQkJbGtrYmRfZGV0ZWN0aW9uX2RvbmUgKGxrKTsKCgkJcmV0dXJuIElSUV9IQU5ETEVEOwoJfQoKCXN3aXRjaCAoZGF0YSkgewoJCWNhc2UgTEtfQUxMX0tFWVNfVVA6CgkJCWlucHV0X3JlZ3MgKCZsay0+ZGV2LCByZWdzKTsKCQkJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUgKGxra2JkX2tleWNvZGUpOyBpKyspCgkJCQlpZiAobGstPmtleWNvZGVbaV0gIT0gS0VZX1JFU0VSVkVEKQoJCQkJCWlucHV0X3JlcG9ydF9rZXkgKCZsay0+ZGV2LCBsay0+a2V5Y29kZVtpXSwgMCk7CgkJCWlucHV0X3N5bmMgKCZsay0+ZGV2KTsKCQkJYnJlYWs7CgkJY2FzZSBMS19NRVRST05PTUU6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfTUVUUk9OT01FIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfT1VUUFVUX0VSUk9SOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX09VVFBVVF9FUlJPUiBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX0lOUFVUX0VSUk9SOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX0lOUFVUX0VSUk9SIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfS0JEX0xPQ0tFRDoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19LQkRfTE9DS0VEIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfS0JEX1RFU1RfTU9ERV9BQ0s6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfS0JEX1RFU1RfTU9ERV9BQ0sgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19QUkVGSVhfS0VZX0RPV046CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfUFJFRklYX0tFWV9ET1dOIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfTU9ERV9DSEFOR0VfQUNLOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX01PREVfQ0hBTkdFX0FDSyBhbmQgaWdub3JlZCAiCgkJCQkJIml0IHByb3Blcmx5Li4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19SRVNQT05TRV9SRVNFUlZFRDoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19SRVNQT05TRV9SRVNFUlZFRCBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIDB4MDE6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgMHgwMSwgc2NoZWR1bGluZyByZS1pbml0aWFsaXphdGlvblxuIik7CgkJCWxrLT5pZ25vcmVfYnl0ZXMgPSBMS19OVU1fSUdOT1JFX0JZVEVTOwoJCQlsay0+aWRbTEtfTlVNX0lHTk9SRV9CWVRFUyAtIGxrLT5pZ25vcmVfYnl0ZXMtLV0gPSBkYXRhOwoJCQlzY2hlZHVsZV93b3JrICgmbGstPnRxKTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCWlmIChsay0+a2V5Y29kZVtkYXRhXSAhPSBLRVlfUkVTRVJWRUQpIHsKCQkJCWlucHV0X3JlZ3MgKCZsay0+ZGV2LCByZWdzKTsKCQkJCWlmICghdGVzdF9iaXQgKGxrLT5rZXljb2RlW2RhdGFdLCBsay0+ZGV2LmtleSkpCgkJCQkJaW5wdXRfcmVwb3J0X2tleSAoJmxrLT5kZXYsIGxrLT5rZXljb2RlW2RhdGFdLCAxKTsKCQkJCWVsc2UKCQkJCQlpbnB1dF9yZXBvcnRfa2V5ICgmbGstPmRldiwgbGstPmtleWNvZGVbZGF0YV0sIDApOwoJCQkJaW5wdXRfc3luYyAoJmxrLT5kZXYpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGsgKEtFUk5fV0FSTklORyAiJXM6IFVua25vd24ga2V5IHdpdGggIgoJCQkJCQkic2NhbmNvZGUgMHglMDJ4IG9uICVzLlxuIiwKCQkJCQkJX19GSUxFX18sIGRhdGEsIGxrLT5uYW1lKTsKCX0KCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCi8qCiAqIGxra2JkX2V2ZW50KCkgaGFuZGxlcyBldmVudHMgZnJvbSB0aGUgaW5wdXQgbW9kdWxlLgogKi8Kc3RhdGljIGludApsa2tiZF9ldmVudCAoc3RydWN0IGlucHV0X2RldiAqZGV2LCB1bnNpZ25lZCBpbnQgdHlwZSwgdW5zaWduZWQgaW50IGNvZGUsCgkJaW50IHZhbHVlKQp7CglzdHJ1Y3QgbGtrYmQgKmxrID0gZGV2LT5wcml2YXRlOwoJdW5zaWduZWQgY2hhciBsZWRzX29uID0gMDsKCXVuc2lnbmVkIGNoYXIgbGVkc19vZmYgPSAwOwoKCXN3aXRjaCAodHlwZSkgewoJCWNhc2UgRVZfTEVEOgoJCQlDSEVDS19MRUQgKExFRF9DQVBTTCwgTEtfTEVEX1NISUZUTE9DSyk7CgkJCUNIRUNLX0xFRCAoTEVEX0NPTVBPU0UsIExLX0xFRF9DT01QT1NFKTsKCQkJQ0hFQ0tfTEVEIChMRURfU0NST0xMTCwgTEtfTEVEX1NDUk9MTExPQ0spOwoJCQlDSEVDS19MRUQgKExFRF9TTEVFUCwgTEtfTEVEX1dBSVQpOwoJCQlpZiAobGVkc19vbiAhPSAwKSB7CgkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9MRURfT04pOwoJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBsZWRzX29uKTsKCQkJfQoJCQlpZiAobGVkc19vZmYgIT0gMCkgewoJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfTEVEX09GRik7CgkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIGxlZHNfb2ZmKTsKCQkJfQoJCQlyZXR1cm4gMDsKCgkJY2FzZSBFVl9TTkQ6CgkJCXN3aXRjaCAoY29kZSkgewoJCQkJY2FzZSBTTkRfQ0xJQ0s6CgkJCQkJaWYgKHZhbHVlID09IDApIHsKCQkJCQkJREJHICgiJXM6IERlYWN0aXZhdGluZyBrZXkgY2xpY2tzXG4iLCBfX0ZVTkNUSU9OX18pOwoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9ESVNBQkxFX0tFWUNMSUNLKTsKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRElTQUJMRV9DVFJDTElDSyk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJREJHICgiJXM6IEFjdGl2YXRpbmcga2V5IGNsaWNrc1xuIiwgX19GVU5DVElPTl9fKTsKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRU5BQkxFX0tFWUNMSUNLKTsKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCB2b2x1bWVfdG9faHcgKGxrLT5rZXljbGlja192b2x1bWUpKTsKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRU5BQkxFX0NUUkNMSUNLKTsKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCB2b2x1bWVfdG9faHcgKGxrLT5jdHJsY2xpY2tfdm9sdW1lKSk7CgkJCQkJfQoJCQkJCXJldHVybiAwOwoKCQkJCWNhc2UgU05EX0JFTEw6CgkJCQkJaWYgKHZhbHVlICE9IDApCgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX1NPVU5EX0JFTEwpOwoKCQkJCQlyZXR1cm4gMDsKCQkJfQoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJcHJpbnRrIChLRVJOX0VSUiAiJXMgKCk6IEdvdCB1bmtub3duIHR5cGUgJWQsIGNvZGUgJWQsIHZhbHVlICVkXG4iLAoJCQkJCV9fRlVOQ1RJT05fXywgdHlwZSwgY29kZSwgdmFsdWUpOwoJfQoKCXJldHVybiAtMTsKfQoKLyoKICogbGtrYmRfcmVpbml0KCkgc2V0cyBsZWRzIGFuZCBiZWVwcyB0byBhIHN0YXRlIHRoZSBjb21wdXRlciByZW1lbWJlcnMgdGhleQogKiB3ZXJlIGluLgogKi8Kc3RhdGljIHZvaWQKbGtrYmRfcmVpbml0ICh2b2lkICpkYXRhKQp7CglzdHJ1Y3QgbGtrYmQgKmxrID0gZGF0YTsKCWludCBkaXZpc2lvbjsKCXVuc2lnbmVkIGNoYXIgbGVkc19vbiA9IDA7Cgl1bnNpZ25lZCBjaGFyIGxlZHNfb2ZmID0gMDsKCgkvKiBBc2sgZm9yIElEICovCglsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9SRVFVRVNUX0lEKTsKCgkvKiBSZXNldCBwYXJhbWV0ZXJzICovCglsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9TRVRfREVGQVVMVFMpOwoKCS8qIFNldCBMRURzICovCglDSEVDS19MRUQgKExFRF9DQVBTTCwgTEtfTEVEX1NISUZUTE9DSyk7CglDSEVDS19MRUQgKExFRF9DT01QT1NFLCBMS19MRURfQ09NUE9TRSk7CglDSEVDS19MRUQgKExFRF9TQ1JPTExMLCBMS19MRURfU0NST0xMTE9DSyk7CglDSEVDS19MRUQgKExFRF9TTEVFUCwgTEtfTEVEX1dBSVQpOwoJaWYgKGxlZHNfb24gIT0gMCkgewoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0xFRF9PTik7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBsZWRzX29uKTsKCX0KCWlmIChsZWRzX29mZiAhPSAwKSB7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfTEVEX09GRik7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBsZWRzX29mZik7Cgl9CgoJLyoKCSAqIFRyeSB0byBhY3RpdmF0ZSBleHRlbmRlZCBMSzQwMSBtb2RlLiBUaGlzIGNvbW1hbmQgd2lsbAoJICogb25seSB3b3JrIHdpdGggYSBMSzQwMSBrZXlib2FyZCBhbmQgZ3JhbnRzIGFjY2VzcyB0bwoJICogTEFsdCwgUkFsdCwgUkNvbXBvc2UgYW5kIFJTaGlmdC4KCSAqLwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRU5BQkxFX0xLNDAxKTsKCgkvKiBTZXQgYWxsIGtleXMgdG8gVVBET1dOIG1vZGUgKi8KCWZvciAoZGl2aXNpb24gPSAxOyBkaXZpc2lvbiA8PSAxNDsgZGl2aXNpb24rKykKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9TRVRfTU9ERSAoTEtfTU9ERV9VUERPV04sCgkJCQkJZGl2aXNpb24pKTsKCgkvKiBFbmFibGUgYmVsbCBhbmQgc2V0IHZvbHVtZSAqLwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRU5BQkxFX0JFTEwpOwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCB2b2x1bWVfdG9faHcgKGxrLT5iZWxsX3ZvbHVtZSkpOwoKCS8qIEVuYWJsZS9kaXNhYmxlIGtleWNsaWNrIChhbmQgcG9zc2libHkgc2V0IHZvbHVtZSkgKi8KCWlmICh0ZXN0X2JpdCAoU05EX0NMSUNLLCBsay0+ZGV2LnNuZCkpIHsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9FTkFCTEVfS0VZQ0xJQ0spOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+a2V5Y2xpY2tfdm9sdW1lKSk7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRU5BQkxFX0NUUkNMSUNLKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIHZvbHVtZV90b19odyAobGstPmN0cmxjbGlja192b2x1bWUpKTsKCX0gZWxzZSB7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRElTQUJMRV9LRVlDTElDSyk7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRElTQUJMRV9DVFJDTElDSyk7Cgl9CgoJLyogU291bmQgdGhlIGJlbGwgaWYgbmVlZGVkICovCglpZiAodGVzdF9iaXQgKFNORF9CRUxMLCBsay0+ZGV2LnNuZCkpCgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfU09VTkRfQkVMTCk7Cn0KCi8qCiAqIGxra2JkX2Nvbm5lY3QoKSBwcm9iZXMgZm9yIGEgTEsga2V5Ym9hcmQgYW5kIGZpbGxzIHRoZSBuZWNlc3Nhcnkgc3RydWN0dXJlcy4KICovCnN0YXRpYyB2b2lkCmxra2JkX2Nvbm5lY3QgKHN0cnVjdCBzZXJpbyAqc2VyaW8sIHN0cnVjdCBzZXJpb19kcml2ZXIgKmRydikKewoJc3RydWN0IGxra2JkICpsazsKCWludCBpOwoKCWlmICgoc2VyaW8tPnR5cGUgJiBTRVJJT19UWVBFKSAhPSBTRVJJT19SUzIzMikKCQlyZXR1cm47CglpZiAoKHNlcmlvLT50eXBlICYgU0VSSU9fUFJPVE8pICE9IFNFUklPX0xLS0JEKQoJCXJldHVybjsKCglpZiAoIShsayA9IGttYWxsb2MgKHNpemVvZiAoc3RydWN0IGxra2JkKSwgR0ZQX0tFUk5FTCkpKQoJCXJldHVybjsKCW1lbXNldCAobGssIDAsIHNpemVvZiAoc3RydWN0IGxra2JkKSk7CgoJaW5pdF9pbnB1dF9kZXYgKCZsay0+ZGV2KTsKCXNldF9iaXQgKEVWX0tFWSwgbGstPmRldi5ldmJpdCk7CglzZXRfYml0IChFVl9MRUQsIGxrLT5kZXYuZXZiaXQpOwoJc2V0X2JpdCAoRVZfU05ELCBsay0+ZGV2LmV2Yml0KTsKCXNldF9iaXQgKEVWX1JFUCwgbGstPmRldi5ldmJpdCk7CglzZXRfYml0IChMRURfQ0FQU0wsIGxrLT5kZXYubGVkYml0KTsKCXNldF9iaXQgKExFRF9TTEVFUCwgbGstPmRldi5sZWRiaXQpOwoJc2V0X2JpdCAoTEVEX0NPTVBPU0UsIGxrLT5kZXYubGVkYml0KTsKCXNldF9iaXQgKExFRF9TQ1JPTExMLCBsay0+ZGV2LmxlZGJpdCk7CglzZXRfYml0IChTTkRfQkVMTCwgbGstPmRldi5zbmRiaXQpOwoJc2V0X2JpdCAoU05EX0NMSUNLLCBsay0+ZGV2LnNuZGJpdCk7CgoJbGstPnNlcmlvID0gc2VyaW87CgoJSU5JVF9XT1JLICgmbGstPnRxLCBsa2tiZF9yZWluaXQsIGxrKTsKCglsay0+YmVsbF92b2x1bWUgPSBiZWxsX3ZvbHVtZTsKCWxrLT5rZXljbGlja192b2x1bWUgPSBrZXljbGlja192b2x1bWU7Cglsay0+Y3RybGNsaWNrX3ZvbHVtZSA9IGN0cmxjbGlja192b2x1bWU7CgoJbGstPmRldi5rZXljb2RlID0gbGstPmtleWNvZGU7Cglsay0+ZGV2LmtleWNvZGVzaXplID0gc2l6ZW9mIChsa19rZXljb2RlX3QpOwoJbGstPmRldi5rZXljb2RlbWF4ID0gTEtfTlVNX0tFWUNPREVTOwoKCWxrLT5kZXYuZXZlbnQgPSBsa2tiZF9ldmVudDsKCWxrLT5kZXYucHJpdmF0ZSA9IGxrOwoKCXNlcmlvLT5wcml2YXRlID0gbGs7CgoJaWYgKHNlcmlvX29wZW4gKHNlcmlvLCBkcnYpKSB7CgkJa2ZyZWUgKGxrKTsKCQlyZXR1cm47Cgl9CgoJc3ByaW50ZiAobGstPm5hbWUsICJERUMgTEsga2V5Ym9hcmQiKTsKCXNwcmludGYgKGxrLT5waHlzLCAiJXMvaW5wdXQwIiwgc2VyaW8tPnBoeXMpOwoKCW1lbWNweSAobGstPmtleWNvZGUsIGxra2JkX2tleWNvZGUsIHNpemVvZiAobGtfa2V5Y29kZV90KSAqIExLX05VTV9LRVlDT0RFUyk7Cglmb3IgKGkgPSAwOyBpIDwgTEtfTlVNX0tFWUNPREVTOyBpKyspCgkJc2V0X2JpdCAobGstPmtleWNvZGVbaV0sIGxrLT5kZXYua2V5Yml0KTsKCglsay0+ZGV2Lm5hbWUgPSBsay0+bmFtZTsKCWxrLT5kZXYucGh5cyA9IGxrLT5waHlzOwoJbGstPmRldi5pZC5idXN0eXBlID0gQlVTX1JTMjMyOwoJbGstPmRldi5pZC52ZW5kb3IgPSBTRVJJT19MS0tCRDsKCWxrLT5kZXYuaWQucHJvZHVjdCA9IDA7Cglsay0+ZGV2LmlkLnZlcnNpb24gPSAweDAxMDA7Cglsay0+ZGV2LmRldiA9ICZzZXJpby0+ZGV2OwoKCWlucHV0X3JlZ2lzdGVyX2RldmljZSAoJmxrLT5kZXYpOwoKCXByaW50ayAoS0VSTl9JTkZPICJpbnB1dDogJXMgb24gJXMsIGluaXRpYXRpbmcgcmVzZXRcbiIsIGxrLT5uYW1lLCBzZXJpby0+cGh5cyk7Cglsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9QT1dFUkNZQ0xFX1JFU0VUKTsKfQoKLyoKICogbGtrYmRfZGlzY29ubmVjdCgpIHVucmVnaXN0ZXJzIGFuZCBjbG9zZXMgYmVoaW5kIHVzLgogKi8Kc3RhdGljIHZvaWQKbGtrYmRfZGlzY29ubmVjdCAoc3RydWN0IHNlcmlvICpzZXJpbykKewoJc3RydWN0IGxra2JkICpsayA9IHNlcmlvLT5wcml2YXRlOwoKCWlucHV0X3VucmVnaXN0ZXJfZGV2aWNlICgmbGstPmRldik7CglzZXJpb19jbG9zZSAoc2VyaW8pOwoJa2ZyZWUgKGxrKTsKfQoKc3RhdGljIHN0cnVjdCBzZXJpb19kcml2ZXIgbGtrYmRfZHJ2ID0gewoJLmRyaXZlcgkJPSB7CgkJLm5hbWUJPSAibGtrYmQiLAoJfSwKCS5kZXNjcmlwdGlvbgk9IERSSVZFUl9ERVNDLAoJLmNvbm5lY3QJPSBsa2tiZF9jb25uZWN0LAoJLmRpc2Nvbm5lY3QJPSBsa2tiZF9kaXNjb25uZWN0LAoJLmludGVycnVwdAk9IGxra2JkX2ludGVycnVwdCwKfTsKCi8qCiAqIFRoZSBmdW5jdGlvbnMgZm9yIGluc2VyaW5nL3JlbW92aW5nIHVzIGFzIGEgbW9kdWxlLgogKi8KaW50IF9faW5pdApsa2tiZF9pbml0ICh2b2lkKQp7CglzZXJpb19yZWdpc3Rlcl9kcml2ZXIoJmxra2JkX2Rydik7CglyZXR1cm4gMDsKfQoKdm9pZCBfX2V4aXQKbGtrYmRfZXhpdCAodm9pZCkKewoJc2VyaW9fdW5yZWdpc3Rlcl9kcml2ZXIoJmxra2JkX2Rydik7Cn0KCm1vZHVsZV9pbml0IChsa2tiZF9pbml0KTsKbW9kdWxlX2V4aXQgKGxra2JkX2V4aXQpOwoK