LyoKICogIENvcHlyaWdodCAoQykgMjAwNCBieSBKYW4tQmVuZWRpY3QgR2xhdyA8amJnbGF3QGx1Zy1vd2wuZGU+CiAqLwoKLyoKICogTEsga2V5Ym9hcmQgZHJpdmVyIGZvciBMaW51eCwgYmFzZWQgb24gc3Vua2JkLmMgKEMpIGJ5IFZvanRlY2ggUGF2bGlrCiAqLwoKLyoKICogREVDIExLMjAxIGFuZCBMSzQwMSBrZXlib2FyZCBkcml2ZXIgZm9yIExpbnV4IChwcmltYXJ5IGZvciBERUNzdGF0aW9ucwogKiBhbmQgVkFYc3RhdGlvbnMsIGJ1dCBjYW4gYWxzbyBiZSB1c2VkIG9uIGFueSBzdGFuZGFyZCBSUzIzMiB3aXRoIGFuCiAqIGFkYXB0b3IpLgogKgogKiBESVNDTEFJTUVSOiBUaGlzIHdvcmtzIGZvciBfbWVfLiBJZiB5b3UgYnJlYWsgYW55dGhpbmcgYnkgdXNpbmcgdGhlCiAqIGluZm9ybWF0aW9uIGdpdmVuIGJlbG93LCBJIHdpbGwgX25vdF8gYmUgbGlhYmxlIQogKgogKiBSSjEwIHBpbm91dDoJCVRvIERFOToJCU9yIERCMjU6CiAqIAkxIC0gUnhEIDwtLS0tPglQaW4gMyAoVHhEKSA8LT4JUGluIDIgKFR4RCkKICogCTIgLSBHTkQgPC0tLS0+CVBpbiA1IChHTkQpIDwtPglQaW4gNyAoR05EKQogKiAJNCAtIFR4RCA8LS0tLT4JUGluIDIgKFJ4RCkgPC0+CVBpbiAzIChSeEQpCiAqIAkzIC0gKzEyViAoZnJvbSBIREQgZHJpdmUgY29ubmVjdG9yKSwgRE9OJ1QgY29ubmVjdCB0byBERTkgb3IgREIyNSEhIQogKgogKiBQaW4gbnVtYmVycyBmb3IgREU5IGFuZCBEQjI1IGFyZSBub3RlZCBvbiB0aGUgcGx1ZyAocXVpdGUgc21hbGw6KS4gRm9yCiAqIFJKMTAsIGl0J3MgbGlrZSB0aGlzOgogKgogKiAgICAgIF9fPV9fCUhvbGQgdGhlIHBsdWcgaW4gZnJvbnQgb2YgeW91LCBjYWJsZSBkb3dud2FyZHMsCiAqICAgICAvX19fL3wJbm9zZSBpcyBoaWRkZW4gYmVoaW5kIHRoZSBwbHVnLiBOb3csIHBpbiAxIGlzIGF0CiAqICAgIHwxMjM0fHwJdGhlIGxlZnQgc2lkZSwgcGluIDQgYXQgdGhlIHJpZ2h0IGFuZCAyIGFuZCAzIGFyZQogKiAgICB8SUlJSXx8CWluIGJldHdlZW4sIG9mIGNvdXJzZTopCiAqICAgIHwgICAgfHwKICogICAgfF9fX198LwogKiAgICAgIHx8CVNvIHRoZSBhZGFwdG9yIGNvbnNpc3RzIG9mIHRocmVlIGNvbm5lY3RlZCBjYWJsZXMKICogICAgICB8fAlmb3IgZGF0YSB0cmFuc21pc3Npb24gKFJ4RCBhbmQgVHhEKSBhbmQgc2lnbmFsIGdyb3VuZC4KICoJCUFkZGl0aW9uYWxseSwgeW91IGhhdmUgdG8gZ2V0ICsxMlYgZnJvbSBzb21ld2hlcmUuCiAqIE1vc3QgZWFzaWx5LCB5b3UnbGwgZ2V0IHRoYXQgZnJvbSBhIGZsb3BweSBvciBIREQgcG93ZXIgY29ubmVjdG9yLgogKiBJdCdzIHRoZSB5ZWxsb3cgY2FibGUgdGhlcmUgKGJsYWNrIGlzIGdyb3VuZCBhbmQgcmVkIGlzICs1VikuCiAqCiAqIFRoZSBrZXlib2FyZCBhbmQgYWxsIHRoZSBjb21tYW5kcyBpdCB1bmRlcnN0YW5kcyBhcmUgZG9jdW1lbnRlZCBpbgogKiAiVkNCMDIgVmlkZW8gU3Vic3lzdGVtIC0gVGVjaG5pY2FsIE1hbnVhbCIsIEVLLTEwNEFBLVRNLTAwMS4gVGhpcwogKiBkb2N1bWVudCBpcyBMSzIwMSBzcGVjaWZpYywgYnV0IExLNDAxIGlzIG1vc3RseSBjb21wYXRpYmxlLiBJdCBjb21lcwogKiB1cCBpbiBMSzIwMSBtb2RlIGFuZCBkb2Vzbid0IHJlcG9ydCBhbnkgb2YgdGhlIGFkZGl0aW9uYWwga2V5cyBpdAogKiBoYXMuIFRoZXNlIG5lZWQgdG8gYmUgc3dpdGNoZWQgb24gd2l0aCB0aGUgTEtfQ01EX0VOQUJMRV9MSzQwMQogKiBjb21tYW5kLiBZb3UnbGwgZmluZCB0aGlzIGRvY3VtZW50IChzY2FubmVkIC5wZGYgZmlsZSkgb24gTUFOWCwKICogYSBzZWFyY2ggZW5naW5lIHNwZWNpZmljIHRvIERFQyBkb2N1bWVudGF0aW9uLiBUcnkKICogaHR0cDovL3d3dy52dDEwMC5uZXQvbWFueC9kZXRhaWxzP3BuPUVLLTEwNEFBLVRNLTAwMTtpZD0yMTtjcD0xCiAqLwoKLyoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICoKICogU2hvdWxkIHlvdSBuZWVkIHRvIGNvbnRhY3QgbWUsIHRoZSBhdXRob3IsIHlvdSBjYW4gZG8gc28gZWl0aGVyIGJ5CiAqIGVtYWlsIG9yIGJ5IHBhcGVyIG1haWw6CiAqIEphbi1CZW5lZGljdCBHbGF3LCBMaWxpZW5zdHJh32UgMTYsIDMzNzkwIEj2cnN0ZSAobmVhciBIYWxsZS9XZXN0Zi4pLAogKiBHZXJtYW55LgogKi8KCiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGVwYXJhbS5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbnB1dC5oPgojaW5jbHVkZSA8bGludXgvc2VyaW8uaD4KI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgoKI2RlZmluZSBEUklWRVJfREVTQwkiTEsga2V5Ym9hcmQgZHJpdmVyIgoKTU9EVUxFX0FVVEhPUiAoIkphbi1CZW5lZGljdCBHbGF3IDxqYmdsYXdAbHVnLW93bC5kZT4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OIChEUklWRVJfREVTQyk7Ck1PRFVMRV9MSUNFTlNFICgiR1BMIik7CgovKgogKiBLbm93biBwYXJhbWV0ZXJzOgogKgliZWxsX3ZvbHVtZQogKglrZXljbGlja192b2x1bWUKICoJY3RybGNsaWNrX3ZvbHVtZQogKgogKiBQbGVhc2Ugbm90aWNlIHRoYXQgdGhlcmUncyBub3QgeWV0IGFuIEFQSSB0byBzZXQgdGhlc2UgYXQgcnVudGltZS4KICovCnN0YXRpYyBpbnQgYmVsbF92b2x1bWUgPSAxMDA7IC8qICUgKi8KbW9kdWxlX3BhcmFtIChiZWxsX3ZvbHVtZSwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyAoYmVsbF92b2x1bWUsICJCZWxsIHZvbHVtZSAoaW4gJSkuIGRlZmF1bHQgaXMgMTAwJSIpOwoKc3RhdGljIGludCBrZXljbGlja192b2x1bWUgPSAxMDA7IC8qICUgKi8KbW9kdWxlX3BhcmFtIChrZXljbGlja192b2x1bWUsIGludCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MgKGtleWNsaWNrX3ZvbHVtZSwgIktleWNsaWNrIHZvbHVtZSAoaW4gJSksIGRlZmF1bHQgaXMgMTAwJSIpOwoKc3RhdGljIGludCBjdHJsY2xpY2tfdm9sdW1lID0gMTAwOyAvKiAlICovCm1vZHVsZV9wYXJhbSAoY3RybGNsaWNrX3ZvbHVtZSwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyAoY3RybGNsaWNrX3ZvbHVtZSwgIkN0cmxjbGljayB2b2x1bWUgKGluICUpLCBkZWZhdWx0IGlzIDEwMCUiKTsKCnN0YXRpYyBpbnQgbGsyMDFfY29tcG9zZV9pc19hbHQgPSAwOwptb2R1bGVfcGFyYW0gKGxrMjAxX2NvbXBvc2VfaXNfYWx0LCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDIChsazIwMV9jb21wb3NlX2lzX2FsdCwgIklmIHNldCBub24temVybywgTEsyMDEnIENvbXBvc2Uga2V5ICIKCQkid2lsbCBhY3QgYXMgYW4gQWx0IGtleSIpOwoKCgojdW5kZWYgTEtLQkRfREVCVUcKI2lmZGVmIExLS0JEX0RFQlVHCiNkZWZpbmUgREJHKHguLi4pIHByaW50ayAoeCkKI2Vsc2UKI2RlZmluZSBEQkcoeC4uLikgZG8ge30gd2hpbGUgKDApCiNlbmRpZgoKLyogTEVEIGNvbnRyb2wgKi8KI2RlZmluZSBMS19MRURfV0FJVAkJMHg4MQojZGVmaW5lIExLX0xFRF9DT01QT1NFCQkweDgyCiNkZWZpbmUgTEtfTEVEX1NISUZUTE9DSwkweDg0CiNkZWZpbmUgTEtfTEVEX1NDUk9MTExPQ0sJMHg4OAojZGVmaW5lIExLX0NNRF9MRURfT04JCTB4MTMKI2RlZmluZSBMS19DTURfTEVEX09GRgkJMHgxMQoKLyogTW9kZSBjb250cm9sICovCiNkZWZpbmUgTEtfTU9ERV9ET1dOCQkweDgwCiNkZWZpbmUgTEtfTU9ERV9BVVRPRE9XTgkweDgyCiNkZWZpbmUgTEtfTU9ERV9VUERPV04JCTB4ODYKI2RlZmluZSBMS19DTURfU0VUX01PREUobW9kZSxkaXYpCSgobW9kZSkgfCAoKGRpdikgPDwgMykpCgovKiBNaXNjIGNvbW1hbmRzICovCiNkZWZpbmUgTEtfQ01EX0VOQUJMRV9LRVlDTElDSwkweDFiCiNkZWZpbmUgTEtfQ01EX0RJU0FCTEVfS0VZQ0xJQ0sJMHg5OQojZGVmaW5lIExLX0NNRF9ESVNBQkxFX0JFTEwJMHhhMQojZGVmaW5lIExLX0NNRF9TT1VORF9CRUxMCTB4YTcKI2RlZmluZSBMS19DTURfRU5BQkxFX0JFTEwJMHgyMwojZGVmaW5lIExLX0NNRF9ESVNBQkxFX0NUUkNMSUNLCTB4YjkKI2RlZmluZSBMS19DTURfRU5BQkxFX0NUUkNMSUNLCTB4YmIKI2RlZmluZSBMS19DTURfU0VUX0RFRkFVTFRTCTB4ZDMKI2RlZmluZSBMS19DTURfUE9XRVJDWUNMRV9SRVNFVAkweGZkCiNkZWZpbmUgTEtfQ01EX0VOQUJMRV9MSzQwMQkweGU5CiNkZWZpbmUgTEtfQ01EX1JFUVVFU1RfSUQJMHhhYgoKLyogTWlzYyByZXNwb25zZXMgZnJvbSBrZXlib2FyZCAqLwojZGVmaW5lIExLX1NUVUNLX0tFWQkJMHgzZAojZGVmaW5lIExLX1NFTEZURVNUX0ZBSUxFRAkweDNlCiNkZWZpbmUgTEtfQUxMX0tFWVNfVVAJCTB4YjMKI2RlZmluZSBMS19NRVRST05PTUUJCTB4YjQKI2RlZmluZSBMS19PVVRQVVRfRVJST1IJCTB4YjUKI2RlZmluZSBMS19JTlBVVF9FUlJPUgkJMHhiNgojZGVmaW5lIExLX0tCRF9MT0NLRUQJCTB4YjcKI2RlZmluZSBMS19LQkRfVEVTVF9NT0RFX0FDSwkweGI4CiNkZWZpbmUgTEtfUFJFRklYX0tFWV9ET1dOCTB4YjkKI2RlZmluZSBMS19NT0RFX0NIQU5HRV9BQ0sJMHhiYQojZGVmaW5lIExLX1JFU1BPTlNFX1JFU0VSVkVECTB4YmIKCiNkZWZpbmUgTEtfTlVNX0tFWUNPREVTCQkyNTYKI2RlZmluZSBMS19OVU1fSUdOT1JFX0JZVEVTCTYKdHlwZWRlZiB1X2ludDE2X3QgbGtfa2V5Y29kZV90OwoKCgpzdGF0aWMgbGtfa2V5Y29kZV90IGxra2JkX2tleWNvZGVbTEtfTlVNX0tFWUNPREVTXSA9IHsKCVsweDU2XSA9IEtFWV9GMSwKCVsweDU3XSA9IEtFWV9GMiwKCVsweDU4XSA9IEtFWV9GMywKCVsweDU5XSA9IEtFWV9GNCwKCVsweDVhXSA9IEtFWV9GNSwKCVsweDY0XSA9IEtFWV9GNiwKCVsweDY1XSA9IEtFWV9GNywKCVsweDY2XSA9IEtFWV9GOCwKCVsweDY3XSA9IEtFWV9GOSwKCVsweDY4XSA9IEtFWV9GMTAsCglbMHg3MV0gPSBLRVlfRjExLAoJWzB4NzJdID0gS0VZX0YxMiwKCVsweDczXSA9IEtFWV9GMTMsCglbMHg3NF0gPSBLRVlfRjE0LAoJWzB4N2NdID0gS0VZX0YxNSwKCVsweDdkXSA9IEtFWV9GMTYsCglbMHg4MF0gPSBLRVlfRjE3LAoJWzB4ODFdID0gS0VZX0YxOCwKCVsweDgyXSA9IEtFWV9GMTksCglbMHg4M10gPSBLRVlfRjIwLAoJWzB4OGFdID0gS0VZX0ZJTkQsCglbMHg4Yl0gPSBLRVlfSU5TRVJULAoJWzB4OGNdID0gS0VZX0RFTEVURSwKCVsweDhkXSA9IEtFWV9TRUxFQ1QsCglbMHg4ZV0gPSBLRVlfUEFHRVVQLAoJWzB4OGZdID0gS0VZX1BBR0VET1dOLAoJWzB4OTJdID0gS0VZX0tQMCwKCVsweDk0XSA9IEtFWV9LUERPVCwKCVsweDk1XSA9IEtFWV9LUEVOVEVSLAoJWzB4OTZdID0gS0VZX0tQMSwKCVsweDk3XSA9IEtFWV9LUDIsCglbMHg5OF0gPSBLRVlfS1AzLAoJWzB4OTldID0gS0VZX0tQNCwKCVsweDlhXSA9IEtFWV9LUDUsCglbMHg5Yl0gPSBLRVlfS1A2LAoJWzB4OWNdID0gS0VZX0tQQ09NTUEsCglbMHg5ZF0gPSBLRVlfS1A3LAoJWzB4OWVdID0gS0VZX0tQOCwKCVsweDlmXSA9IEtFWV9LUDksCglbMHhhMF0gPSBLRVlfS1BNSU5VUywKCVsweGExXSA9IEtFWV9QUk9HMSwKCVsweGEyXSA9IEtFWV9QUk9HMiwKCVsweGEzXSA9IEtFWV9QUk9HMywKCVsweGE0XSA9IEtFWV9QUk9HNCwKCVsweGE3XSA9IEtFWV9MRUZULAoJWzB4YThdID0gS0VZX1JJR0hULAoJWzB4YTldID0gS0VZX0RPV04sCglbMHhhYV0gPSBLRVlfVVAsCglbMHhhYl0gPSBLRVlfUklHSFRTSElGVCwKCVsweGFjXSA9IEtFWV9MRUZUQUxULAoJWzB4YWRdID0gS0VZX0NPTVBPU0UsIC8qIFJpZ2h0IENvbXBvc2UsIHRoYXQgaXMuICovCglbMHhhZV0gPSBLRVlfTEVGVFNISUZULCAvKiBTYW1lIGFzIEtFWV9SSUdIVFNISUZUIG9uIExLMjAxICovCglbMHhhZl0gPSBLRVlfTEVGVENUUkwsCglbMHhiMF0gPSBLRVlfQ0FQU0xPQ0ssCglbMHhiMV0gPSBLRVlfQ09NUE9TRSwgLyogTGVmdCBDb21wb3NlLCB0aGF0IGlzLiAqLwoJWzB4YjJdID0gS0VZX1JJR0hUQUxULAoJWzB4YmNdID0gS0VZX0JBQ0tTUEFDRSwKCVsweGJkXSA9IEtFWV9FTlRFUiwKCVsweGJlXSA9IEtFWV9UQUIsCglbMHhiZl0gPSBLRVlfRVNDLAoJWzB4YzBdID0gS0VZXzEsCglbMHhjMV0gPSBLRVlfUSwKCVsweGMyXSA9IEtFWV9BLAoJWzB4YzNdID0gS0VZX1osCglbMHhjNV0gPSBLRVlfMiwKCVsweGM2XSA9IEtFWV9XLAoJWzB4YzddID0gS0VZX1MsCglbMHhjOF0gPSBLRVlfWCwKCVsweGM5XSA9IEtFWV8xMDJORCwKCVsweGNiXSA9IEtFWV8zLAoJWzB4Y2NdID0gS0VZX0UsCglbMHhjZF0gPSBLRVlfRCwKCVsweGNlXSA9IEtFWV9DLAoJWzB4ZDBdID0gS0VZXzQsCglbMHhkMV0gPSBLRVlfUiwKCVsweGQyXSA9IEtFWV9GLAoJWzB4ZDNdID0gS0VZX1YsCglbMHhkNF0gPSBLRVlfU1BBQ0UsCglbMHhkNl0gPSBLRVlfNSwKCVsweGQ3XSA9IEtFWV9ULAoJWzB4ZDhdID0gS0VZX0csCglbMHhkOV0gPSBLRVlfQiwKCVsweGRiXSA9IEtFWV82LAoJWzB4ZGNdID0gS0VZX1ksCglbMHhkZF0gPSBLRVlfSCwKCVsweGRlXSA9IEtFWV9OLAoJWzB4ZTBdID0gS0VZXzcsCglbMHhlMV0gPSBLRVlfVSwKCVsweGUyXSA9IEtFWV9KLAoJWzB4ZTNdID0gS0VZX00sCglbMHhlNV0gPSBLRVlfOCwKCVsweGU2XSA9IEtFWV9JLAoJWzB4ZTddID0gS0VZX0ssCglbMHhlOF0gPSBLRVlfQ09NTUEsCglbMHhlYV0gPSBLRVlfOSwKCVsweGViXSA9IEtFWV9PLAoJWzB4ZWNdID0gS0VZX0wsCglbMHhlZF0gPSBLRVlfRE9ULAoJWzB4ZWZdID0gS0VZXzAsCglbMHhmMF0gPSBLRVlfUCwKCVsweGYyXSA9IEtFWV9TRU1JQ09MT04sCglbMHhmM10gPSBLRVlfU0xBU0gsCglbMHhmNV0gPSBLRVlfRVFVQUwsCglbMHhmNl0gPSBLRVlfUklHSFRCUkFDRSwKCVsweGY3XSA9IEtFWV9CQUNLU0xBU0gsCglbMHhmOV0gPSBLRVlfTUlOVVMsCglbMHhmYV0gPSBLRVlfTEVGVEJSQUNFLAoJWzB4ZmJdID0gS0VZX0FQT1NUUk9QSEUsCn07CgojZGVmaW5lIENIRUNLX0xFRChMRUQsIEJJVFMpIGRvIHsJCVwKCWlmICh0ZXN0X2JpdCAoTEVELCBsay0+ZGV2LmxlZCkpCVwKCQlsZWRzX29uIHw9IEJJVFM7CQlcCgllbHNlCQkJCQlcCgkJbGVkc19vZmYgfD0gQklUUzsJCVwKCX0gd2hpbGUgKDApCgovKgogKiBQZXIta2V5Ym9hcmQgZGF0YQogKi8Kc3RydWN0IGxra2JkIHsKCWxrX2tleWNvZGVfdCBrZXljb2RlW0xLX05VTV9LRVlDT0RFU107CglpbnQgaWdub3JlX2J5dGVzOwoJdW5zaWduZWQgY2hhciBpZFtMS19OVU1fSUdOT1JFX0JZVEVTXTsKCXN0cnVjdCBpbnB1dF9kZXYgZGV2OwoJc3RydWN0IHNlcmlvICpzZXJpbzsKCXN0cnVjdCB3b3JrX3N0cnVjdCB0cTsKCWNoYXIgbmFtZVs2NF07CgljaGFyIHBoeXNbMzJdOwoJY2hhciB0eXBlOwoJaW50IGJlbGxfdm9sdW1lOwoJaW50IGtleWNsaWNrX3ZvbHVtZTsKCWludCBjdHJsY2xpY2tfdm9sdW1lOwp9OwoKLyoKICogQ2FsY3VsYXRlIHZvbHVtZSBwYXJhbWV0ZXIgYnl0ZSBmb3IgYSBnaXZlbiB2b2x1bWUuCiAqLwpzdGF0aWMgdW5zaWduZWQgY2hhcgp2b2x1bWVfdG9faHcgKGludCB2b2x1bWVfcGVyY2VudCkKewoJdW5zaWduZWQgY2hhciByZXQgPSAwOwoKCWlmICh2b2x1bWVfcGVyY2VudCA8IDApCgkJdm9sdW1lX3BlcmNlbnQgPSAwOwoJaWYgKHZvbHVtZV9wZXJjZW50ID4gMTAwKQoJCXZvbHVtZV9wZXJjZW50ID0gMTAwOwoKCWlmICh2b2x1bWVfcGVyY2VudCA+PSAwKQoJCXJldCA9IDc7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gMTMpCS8qIDEyLjUgKi8KCQlyZXQgPSA2OwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDI1KQoJCXJldCA9IDU7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gMzgpCS8qIDM3LjUgKi8KCQlyZXQgPSA0OwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDUwKQoJCXJldCA9IDM7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gNjMpCS8qIDYyLjUgKi8KCQlyZXQgPSAyOwkJLyogVGhpcyBpcyB0aGUgZGVmYXVsdCB2b2x1bWUgKi8KCWlmICh2b2x1bWVfcGVyY2VudCA+PSA3NSkKCQlyZXQgPSAxOwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDg4KQkvKiA4Ny41ICovCgkJcmV0ID0gMDsKCglyZXQgfD0gMHg4MDsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZApsa2tiZF9kZXRlY3Rpb25fZG9uZSAoc3RydWN0IGxra2JkICpsaykKewoJaW50IGk7CgoJLyoKCSAqIFJlc2V0IHNldHRpbmcgZm9yIENvbXBvc2Uga2V5LiBMZXQgQ29tcG9zZSBiZSBLRVlfQ09NUE9TRS4KCSAqLwoJbGstPmtleWNvZGVbMHhiMV0gPSBLRVlfQ09NUE9TRTsKCgkvKgoJICogUHJpbnQga2V5Ym9hcmQgbmFtZSBhbmQgbW9kaWZ5IENvbXBvc2U9QWx0IG9uIHVzZXIncyByZXF1ZXN0LgoJICovCglzd2l0Y2ggKGxrLT5pZFs0XSkgewoJCWNhc2UgMToKCQkJc3ByaW50ZiAobGstPm5hbWUsICJERUMgTEsyMDEga2V5Ym9hcmQiKTsKCgkJCWlmIChsazIwMV9jb21wb3NlX2lzX2FsdCkKCQkJCWxrLT5rZXljb2RlWzB4YjFdID0gS0VZX0xFRlRBTFQ7CgkJCWJyZWFrOwoKCQljYXNlIDI6CgkJCXNwcmludGYgKGxrLT5uYW1lLCAiREVDIExLNDAxIGtleWJvYXJkIik7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlzcHJpbnRmIChsay0+bmFtZSwgIlVua25vd24gREVDIGtleWJvYXJkIik7CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBrZXlib2FyZCBvbiAlcyBpcyB1bmtub3duLCAiCgkJCQkJInBsZWFzZSByZXBvcnQgdG8gSmFuLUJlbmVkaWN0IEdsYXcgIgoJCQkJCSI8amJnbGF3QGx1Zy1vd2wuZGU+XG4iLCBsay0+cGh5cyk7CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBrZXlib2FyZCBJRCdlZCBhczoiKTsKCQkJZm9yIChpID0gMDsgaSA8IExLX05VTV9JR05PUkVfQllURVM7IGkrKykKCQkJCXByaW50ayAoIiAweCUwMngiLCBsay0+aWRbaV0pOwoJCQlwcmludGsgKCJcbiIpOwoJCQlicmVhazsKCX0KCXByaW50ayAoS0VSTl9JTkZPICJsa2tiZDoga2V5Ym9hcmQgb24gJXMgaWRlbnRpZmllZCBhczogJXNcbiIsCgkJCWxrLT5waHlzLCBsay0+bmFtZSk7CgoJLyoKCSAqIFJlcG9ydCBlcnJvcnMgZHVyaW5nIGtleWJvYXJkIGJvb3QtdXAuCgkgKi8KCXN3aXRjaCAobGstPmlkWzJdKSB7CgkJY2FzZSAweDAwOgoJCQkvKiBBbGwgb2theSAqLwoJCQlicmVhazsKCgkJY2FzZSBMS19TVFVDS19LRVk6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBTdHVjayBrZXkgb24ga2V5Ym9hcmQgYXQgIgoJCQkJCSIlc1xuIiwgbGstPnBoeXMpOwoJCQlicmVhazsKCgkJY2FzZSBMS19TRUxGVEVTVF9GQUlMRUQ6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBTZWxmdGVzdCBmYWlsZWQgb24ga2V5Ym9hcmQgIgoJCQkJCSJhdCAlcywga2V5Ym9hcmQgbWF5IG5vdCB3b3JrICIKCQkJCQkicHJvcGVybHlcbiIsIGxrLT5waHlzKTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBVbmtub3duIGVycm9yICUwMnggb24gIgoJCQkJCSJrZXlib2FyZCBhdCAlc1xuIiwgbGstPmlkWzJdLAoJCQkJCWxrLT5waHlzKTsKCQkJYnJlYWs7Cgl9CgoJLyoKCSAqIFRyeSB0byBoaW50IHVzZXIgaWYgdGhlcmUncyBhIHN0dWNrIGtleS4KCSAqLwoJaWYgKGxrLT5pZFsyXSA9PSBMS19TVFVDS19LRVkgJiYgbGstPmlkWzNdICE9IDApCgkJcHJpbnRrIChLRVJOX0VSUiAiU2NhbmNvZGUgb2Ygc3R1Y2sga2V5IGlzIDB4JTAyeCwga2V5Y29kZSAiCgkJCQkiaXMgMHglMDR4XG4iLCBsay0+aWRbM10sCgkJCQlsay0+a2V5Y29kZVtsay0+aWRbM11dKTsKCglyZXR1cm47Cn0KCi8qCiAqIGxra2JkX2ludGVycnVwdCgpIGlzIGNhbGxlZCBieSB0aGUgbG93IGxldmVsIGRyaXZlciB3aGVuIGEgY2hhcmFjdGVyCiAqIGlzIHJlY2VpdmVkLgogKi8Kc3RhdGljIGlycXJldHVybl90Cmxra2JkX2ludGVycnVwdCAoc3RydWN0IHNlcmlvICpzZXJpbywgdW5zaWduZWQgY2hhciBkYXRhLCB1bnNpZ25lZCBpbnQgZmxhZ3MsCgkJc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBsa2tiZCAqbGsgPSBzZXJpb19nZXRfZHJ2ZGF0YSAoc2VyaW8pOwoJaW50IGk7CgoJREJHIChLRVJOX0lORk8gIkdvdCBieXRlIDB4JTAyeFxuIiwgZGF0YSk7CgoJaWYgKGxrLT5pZ25vcmVfYnl0ZXMgPiAwKSB7CgkJREJHIChLRVJOX0lORk8gIklnbm9yaW5nIGEgYnl0ZSBvbiAlc1xuIiwKCQkJCWxrLT5uYW1lKTsKCQlsay0+aWRbTEtfTlVNX0lHTk9SRV9CWVRFUyAtIGxrLT5pZ25vcmVfYnl0ZXMtLV0gPSBkYXRhOwoKCQlpZiAobGstPmlnbm9yZV9ieXRlcyA9PSAwKQoJCQlsa2tiZF9kZXRlY3Rpb25fZG9uZSAobGspOwoKCQlyZXR1cm4gSVJRX0hBTkRMRUQ7Cgl9CgoJc3dpdGNoIChkYXRhKSB7CgkJY2FzZSBMS19BTExfS0VZU19VUDoKCQkJaW5wdXRfcmVncyAoJmxrLT5kZXYsIHJlZ3MpOwoJCQlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRSAobGtrYmRfa2V5Y29kZSk7IGkrKykKCQkJCWlmIChsay0+a2V5Y29kZVtpXSAhPSBLRVlfUkVTRVJWRUQpCgkJCQkJaW5wdXRfcmVwb3J0X2tleSAoJmxrLT5kZXYsIGxrLT5rZXljb2RlW2ldLCAwKTsKCQkJaW5wdXRfc3luYyAoJmxrLT5kZXYpOwoJCQlicmVhazsKCQljYXNlIExLX01FVFJPTk9NRToKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19NRVRST05PTUUgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19PVVRQVVRfRVJST1I6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfT1VUUFVUX0VSUk9SIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfSU5QVVRfRVJST1I6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfSU5QVVRfRVJST1IgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19LQkRfTE9DS0VEOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX0tCRF9MT0NLRUQgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19LQkRfVEVTVF9NT0RFX0FDSzoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19LQkRfVEVTVF9NT0RFX0FDSyBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX1BSRUZJWF9LRVlfRE9XTjoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19QUkVGSVhfS0VZX0RPV04gYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19NT0RFX0NIQU5HRV9BQ0s6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfTU9ERV9DSEFOR0VfQUNLIGFuZCBpZ25vcmVkICIKCQkJCQkiaXQgcHJvcGVybHkuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX1JFU1BPTlNFX1JFU0VSVkVEOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX1JFU1BPTlNFX1JFU0VSVkVEIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgMHgwMToKCQkJREJHIChLRVJOX0lORk8gIkdvdCAweDAxLCBzY2hlZHVsaW5nIHJlLWluaXRpYWxpemF0aW9uXG4iKTsKCQkJbGstPmlnbm9yZV9ieXRlcyA9IExLX05VTV9JR05PUkVfQllURVM7CgkJCWxrLT5pZFtMS19OVU1fSUdOT1JFX0JZVEVTIC0gbGstPmlnbm9yZV9ieXRlcy0tXSA9IGRhdGE7CgkJCXNjaGVkdWxlX3dvcmsgKCZsay0+dHEpOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJaWYgKGxrLT5rZXljb2RlW2RhdGFdICE9IEtFWV9SRVNFUlZFRCkgewoJCQkJaW5wdXRfcmVncyAoJmxrLT5kZXYsIHJlZ3MpOwoJCQkJaWYgKCF0ZXN0X2JpdCAobGstPmtleWNvZGVbZGF0YV0sIGxrLT5kZXYua2V5KSkKCQkJCQlpbnB1dF9yZXBvcnRfa2V5ICgmbGstPmRldiwgbGstPmtleWNvZGVbZGF0YV0sIDEpOwoJCQkJZWxzZQoJCQkJCWlucHV0X3JlcG9ydF9rZXkgKCZsay0+ZGV2LCBsay0+a2V5Y29kZVtkYXRhXSwgMCk7CgkJCQlpbnB1dF9zeW5jICgmbGstPmRldik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ayAoS0VSTl9XQVJOSU5HICIlczogVW5rbm93biBrZXkgd2l0aCAiCgkJCQkJCSJzY2FuY29kZSAweCUwMnggb24gJXMuXG4iLAoJCQkJCQlfX0ZJTEVfXywgZGF0YSwgbGstPm5hbWUpOwoJfQoKCXJldHVybiBJUlFfSEFORExFRDsKfQoKLyoKICogbGtrYmRfZXZlbnQoKSBoYW5kbGVzIGV2ZW50cyBmcm9tIHRoZSBpbnB1dCBtb2R1bGUuCiAqLwpzdGF0aWMgaW50Cmxra2JkX2V2ZW50IChzdHJ1Y3QgaW5wdXRfZGV2ICpkZXYsIHVuc2lnbmVkIGludCB0eXBlLCB1bnNpZ25lZCBpbnQgY29kZSwKCQlpbnQgdmFsdWUpCnsKCXN0cnVjdCBsa2tiZCAqbGsgPSBkZXYtPnByaXZhdGU7Cgl1bnNpZ25lZCBjaGFyIGxlZHNfb24gPSAwOwoJdW5zaWduZWQgY2hhciBsZWRzX29mZiA9IDA7CgoJc3dpdGNoICh0eXBlKSB7CgkJY2FzZSBFVl9MRUQ6CgkJCUNIRUNLX0xFRCAoTEVEX0NBUFNMLCBMS19MRURfU0hJRlRMT0NLKTsKCQkJQ0hFQ0tfTEVEIChMRURfQ09NUE9TRSwgTEtfTEVEX0NPTVBPU0UpOwoJCQlDSEVDS19MRUQgKExFRF9TQ1JPTExMLCBMS19MRURfU0NST0xMTE9DSyk7CgkJCUNIRUNLX0xFRCAoTEVEX1NMRUVQLCBMS19MRURfV0FJVCk7CgkJCWlmIChsZWRzX29uICE9IDApIHsKCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0xFRF9PTik7CgkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIGxlZHNfb24pOwoJCQl9CgkJCWlmIChsZWRzX29mZiAhPSAwKSB7CgkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9MRURfT0ZGKTsKCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgbGVkc19vZmYpOwoJCQl9CgkJCXJldHVybiAwOwoKCQljYXNlIEVWX1NORDoKCQkJc3dpdGNoIChjb2RlKSB7CgkJCQljYXNlIFNORF9DTElDSzoKCQkJCQlpZiAodmFsdWUgPT0gMCkgewoJCQkJCQlEQkcgKCIlczogRGVhY3RpdmF0aW5nIGtleSBjbGlja3NcbiIsIF9fRlVOQ1RJT05fXyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0RJU0FCTEVfS0VZQ0xJQ0spOwoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9ESVNBQkxFX0NUUkNMSUNLKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlEQkcgKCIlczogQWN0aXZhdGluZyBrZXkgY2xpY2tzXG4iLCBfX0ZVTkNUSU9OX18pOwoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9FTkFCTEVfS0VZQ0xJQ0spOwoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIHZvbHVtZV90b19odyAobGstPmtleWNsaWNrX3ZvbHVtZSkpOwoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9FTkFCTEVfQ1RSQ0xJQ0spOwoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIHZvbHVtZV90b19odyAobGstPmN0cmxjbGlja192b2x1bWUpKTsKCQkJCQl9CgkJCQkJcmV0dXJuIDA7CgoJCQkJY2FzZSBTTkRfQkVMTDoKCQkJCQlpZiAodmFsdWUgIT0gMCkKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfU09VTkRfQkVMTCk7CgoJCQkJCXJldHVybiAwOwoJCQl9CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlwcmludGsgKEtFUk5fRVJSICIlcyAoKTogR290IHVua25vd24gdHlwZSAlZCwgY29kZSAlZCwgdmFsdWUgJWRcbiIsCgkJCQkJX19GVU5DVElPTl9fLCB0eXBlLCBjb2RlLCB2YWx1ZSk7Cgl9CgoJcmV0dXJuIC0xOwp9CgovKgogKiBsa2tiZF9yZWluaXQoKSBzZXRzIGxlZHMgYW5kIGJlZXBzIHRvIGEgc3RhdGUgdGhlIGNvbXB1dGVyIHJlbWVtYmVycyB0aGV5CiAqIHdlcmUgaW4uCiAqLwpzdGF0aWMgdm9pZApsa2tiZF9yZWluaXQgKHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBsa2tiZCAqbGsgPSBkYXRhOwoJaW50IGRpdmlzaW9uOwoJdW5zaWduZWQgY2hhciBsZWRzX29uID0gMDsKCXVuc2lnbmVkIGNoYXIgbGVkc19vZmYgPSAwOwoKCS8qIEFzayBmb3IgSUQgKi8KCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX1JFUVVFU1RfSUQpOwoKCS8qIFJlc2V0IHBhcmFtZXRlcnMgKi8KCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX1NFVF9ERUZBVUxUUyk7CgoJLyogU2V0IExFRHMgKi8KCUNIRUNLX0xFRCAoTEVEX0NBUFNMLCBMS19MRURfU0hJRlRMT0NLKTsKCUNIRUNLX0xFRCAoTEVEX0NPTVBPU0UsIExLX0xFRF9DT01QT1NFKTsKCUNIRUNLX0xFRCAoTEVEX1NDUk9MTEwsIExLX0xFRF9TQ1JPTExMT0NLKTsKCUNIRUNLX0xFRCAoTEVEX1NMRUVQLCBMS19MRURfV0FJVCk7CglpZiAobGVkc19vbiAhPSAwKSB7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfTEVEX09OKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIGxlZHNfb24pOwoJfQoJaWYgKGxlZHNfb2ZmICE9IDApIHsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9MRURfT0ZGKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIGxlZHNfb2ZmKTsKCX0KCgkvKgoJICogVHJ5IHRvIGFjdGl2YXRlIGV4dGVuZGVkIExLNDAxIG1vZGUuIFRoaXMgY29tbWFuZCB3aWxsCgkgKiBvbmx5IHdvcmsgd2l0aCBhIExLNDAxIGtleWJvYXJkIGFuZCBncmFudHMgYWNjZXNzIHRvCgkgKiBMQWx0LCBSQWx0LCBSQ29tcG9zZSBhbmQgUlNoaWZ0LgoJICovCglsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9FTkFCTEVfTEs0MDEpOwoKCS8qIFNldCBhbGwga2V5cyB0byBVUERPV04gbW9kZSAqLwoJZm9yIChkaXZpc2lvbiA9IDE7IGRpdmlzaW9uIDw9IDE0OyBkaXZpc2lvbisrKQoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX1NFVF9NT0RFIChMS19NT0RFX1VQRE9XTiwKCQkJCQlkaXZpc2lvbikpOwoKCS8qIEVuYWJsZSBiZWxsIGFuZCBzZXQgdm9sdW1lICovCglsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9FTkFCTEVfQkVMTCk7Cglsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIHZvbHVtZV90b19odyAobGstPmJlbGxfdm9sdW1lKSk7CgoJLyogRW5hYmxlL2Rpc2FibGUga2V5Y2xpY2sgKGFuZCBwb3NzaWJseSBzZXQgdm9sdW1lKSAqLwoJaWYgKHRlc3RfYml0IChTTkRfQ0xJQ0ssIGxrLT5kZXYuc25kKSkgewoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9LRVlDTElDSyk7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCB2b2x1bWVfdG9faHcgKGxrLT5rZXljbGlja192b2x1bWUpKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9FTkFCTEVfQ1RSQ0xJQ0spOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+Y3RybGNsaWNrX3ZvbHVtZSkpOwoJfSBlbHNlIHsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9ESVNBQkxFX0tFWUNMSUNLKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9ESVNBQkxFX0NUUkNMSUNLKTsKCX0KCgkvKiBTb3VuZCB0aGUgYmVsbCBpZiBuZWVkZWQgKi8KCWlmICh0ZXN0X2JpdCAoU05EX0JFTEwsIGxrLT5kZXYuc25kKSkKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9TT1VORF9CRUxMKTsKfQoKLyoKICogbGtrYmRfY29ubmVjdCgpIHByb2JlcyBmb3IgYSBMSyBrZXlib2FyZCBhbmQgZmlsbHMgdGhlIG5lY2Vzc2FyeSBzdHJ1Y3R1cmVzLgogKi8Kc3RhdGljIGludApsa2tiZF9jb25uZWN0IChzdHJ1Y3Qgc2VyaW8gKnNlcmlvLCBzdHJ1Y3Qgc2VyaW9fZHJpdmVyICpkcnYpCnsKCXN0cnVjdCBsa2tiZCAqbGs7CglpbnQgaTsKCWludCBlcnI7CgoJaWYgKCEobGsgPSBrbWFsbG9jIChzaXplb2YgKHN0cnVjdCBsa2tiZCksIEdGUF9LRVJORUwpKSkKCQlyZXR1cm4gLUVOT01FTTsKCgltZW1zZXQgKGxrLCAwLCBzaXplb2YgKHN0cnVjdCBsa2tiZCkpOwoKCWluaXRfaW5wdXRfZGV2ICgmbGstPmRldik7CglzZXRfYml0IChFVl9LRVksIGxrLT5kZXYuZXZiaXQpOwoJc2V0X2JpdCAoRVZfTEVELCBsay0+ZGV2LmV2Yml0KTsKCXNldF9iaXQgKEVWX1NORCwgbGstPmRldi5ldmJpdCk7CglzZXRfYml0IChFVl9SRVAsIGxrLT5kZXYuZXZiaXQpOwoJc2V0X2JpdCAoTEVEX0NBUFNMLCBsay0+ZGV2LmxlZGJpdCk7CglzZXRfYml0IChMRURfU0xFRVAsIGxrLT5kZXYubGVkYml0KTsKCXNldF9iaXQgKExFRF9DT01QT1NFLCBsay0+ZGV2LmxlZGJpdCk7CglzZXRfYml0IChMRURfU0NST0xMTCwgbGstPmRldi5sZWRiaXQpOwoJc2V0X2JpdCAoU05EX0JFTEwsIGxrLT5kZXYuc25kYml0KTsKCXNldF9iaXQgKFNORF9DTElDSywgbGstPmRldi5zbmRiaXQpOwoKCWxrLT5zZXJpbyA9IHNlcmlvOwoKCUlOSVRfV09SSyAoJmxrLT50cSwgbGtrYmRfcmVpbml0LCBsayk7CgoJbGstPmJlbGxfdm9sdW1lID0gYmVsbF92b2x1bWU7Cglsay0+a2V5Y2xpY2tfdm9sdW1lID0ga2V5Y2xpY2tfdm9sdW1lOwoJbGstPmN0cmxjbGlja192b2x1bWUgPSBjdHJsY2xpY2tfdm9sdW1lOwoKCWxrLT5kZXYua2V5Y29kZSA9IGxrLT5rZXljb2RlOwoJbGstPmRldi5rZXljb2Rlc2l6ZSA9IHNpemVvZiAobGtfa2V5Y29kZV90KTsKCWxrLT5kZXYua2V5Y29kZW1heCA9IExLX05VTV9LRVlDT0RFUzsKCglsay0+ZGV2LmV2ZW50ID0gbGtrYmRfZXZlbnQ7Cglsay0+ZGV2LnByaXZhdGUgPSBsazsKCglzZXJpb19zZXRfZHJ2ZGF0YSAoc2VyaW8sIGxrKTsKCgllcnIgPSBzZXJpb19vcGVuIChzZXJpbywgZHJ2KTsKCWlmIChlcnIpIHsKCQlzZXJpb19zZXRfZHJ2ZGF0YSAoc2VyaW8sIE5VTEwpOwoJCWtmcmVlIChsayk7CgkJcmV0dXJuIGVycjsKCX0KCglzcHJpbnRmIChsay0+bmFtZSwgIkRFQyBMSyBrZXlib2FyZCIpOwoJc3ByaW50ZiAobGstPnBoeXMsICIlcy9pbnB1dDAiLCBzZXJpby0+cGh5cyk7CgoJbWVtY3B5IChsay0+a2V5Y29kZSwgbGtrYmRfa2V5Y29kZSwgc2l6ZW9mIChsa19rZXljb2RlX3QpICogTEtfTlVNX0tFWUNPREVTKTsKCWZvciAoaSA9IDA7IGkgPCBMS19OVU1fS0VZQ09ERVM7IGkrKykKCQlzZXRfYml0IChsay0+a2V5Y29kZVtpXSwgbGstPmRldi5rZXliaXQpOwoKCWxrLT5kZXYubmFtZSA9IGxrLT5uYW1lOwoJbGstPmRldi5waHlzID0gbGstPnBoeXM7Cglsay0+ZGV2LmlkLmJ1c3R5cGUgPSBCVVNfUlMyMzI7Cglsay0+ZGV2LmlkLnZlbmRvciA9IFNFUklPX0xLS0JEOwoJbGstPmRldi5pZC5wcm9kdWN0ID0gMDsKCWxrLT5kZXYuaWQudmVyc2lvbiA9IDB4MDEwMDsKCWxrLT5kZXYuZGV2ID0gJnNlcmlvLT5kZXY7CgoJaW5wdXRfcmVnaXN0ZXJfZGV2aWNlICgmbGstPmRldik7CgoJcHJpbnRrIChLRVJOX0lORk8gImlucHV0OiAlcyBvbiAlcywgaW5pdGlhdGluZyByZXNldFxuIiwgbGstPm5hbWUsIHNlcmlvLT5waHlzKTsKCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX1BPV0VSQ1lDTEVfUkVTRVQpOwoKCXJldHVybiAwOwp9CgovKgogKiBsa2tiZF9kaXNjb25uZWN0KCkgdW5yZWdpc3RlcnMgYW5kIGNsb3NlcyBiZWhpbmQgdXMuCiAqLwpzdGF0aWMgdm9pZApsa2tiZF9kaXNjb25uZWN0IChzdHJ1Y3Qgc2VyaW8gKnNlcmlvKQp7CglzdHJ1Y3QgbGtrYmQgKmxrID0gc2VyaW9fZ2V0X2RydmRhdGEgKHNlcmlvKTsKCglpbnB1dF91bnJlZ2lzdGVyX2RldmljZSAoJmxrLT5kZXYpOwoJc2VyaW9fY2xvc2UgKHNlcmlvKTsKCXNlcmlvX3NldF9kcnZkYXRhIChzZXJpbywgTlVMTCk7CglrZnJlZSAobGspOwp9CgpzdGF0aWMgc3RydWN0IHNlcmlvX2RldmljZV9pZCBsa2tiZF9zZXJpb19pZHNbXSA9IHsKCXsKCQkudHlwZQk9IFNFUklPX1JTMjMyLAoJCS5wcm90bwk9IFNFUklPX0xLS0JELAoJCS5pZAk9IFNFUklPX0FOWSwKCQkuZXh0cmEJPSBTRVJJT19BTlksCgl9LAoJeyAwIH0KfTsKCk1PRFVMRV9ERVZJQ0VfVEFCTEUoc2VyaW8sIGxra2JkX3NlcmlvX2lkcyk7CgpzdGF0aWMgc3RydWN0IHNlcmlvX2RyaXZlciBsa2tiZF9kcnYgPSB7CgkuZHJpdmVyCQk9IHsKCQkubmFtZQk9ICJsa2tiZCIsCgl9LAoJLmRlc2NyaXB0aW9uCT0gRFJJVkVSX0RFU0MsCgkuaWRfdGFibGUJPSBsa2tiZF9zZXJpb19pZHMsCgkuY29ubmVjdAk9IGxra2JkX2Nvbm5lY3QsCgkuZGlzY29ubmVjdAk9IGxra2JkX2Rpc2Nvbm5lY3QsCgkuaW50ZXJydXB0CT0gbGtrYmRfaW50ZXJydXB0LAp9OwoKLyoKICogVGhlIGZ1bmN0aW9ucyBmb3IgaW5zZXJpbmcvcmVtb3ZpbmcgdXMgYXMgYSBtb2R1bGUuCiAqLwpzdGF0aWMgaW50IF9faW5pdApsa2tiZF9pbml0ICh2b2lkKQp7CglzZXJpb19yZWdpc3Rlcl9kcml2ZXIoJmxra2JkX2Rydik7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgX19leGl0Cmxra2JkX2V4aXQgKHZvaWQpCnsKCXNlcmlvX3VucmVnaXN0ZXJfZHJpdmVyKCZsa2tiZF9kcnYpOwp9Cgptb2R1bGVfaW5pdCAobGtrYmRfaW5pdCk7Cm1vZHVsZV9leGl0IChsa2tiZF9leGl0KTsKCg==