LyoKICogIENvcHlyaWdodCAoQykgMjAwNCBieSBKYW4tQmVuZWRpY3QgR2xhdyA8amJnbGF3QGx1Zy1vd2wuZGU+CiAqLwoKLyoKICogTEsga2V5Ym9hcmQgZHJpdmVyIGZvciBMaW51eCwgYmFzZWQgb24gc3Vua2JkLmMgKEMpIGJ5IFZvanRlY2ggUGF2bGlrCiAqLwoKLyoKICogREVDIExLMjAxIGFuZCBMSzQwMSBrZXlib2FyZCBkcml2ZXIgZm9yIExpbnV4IChwcmltYXJ5IGZvciBERUNzdGF0aW9ucwogKiBhbmQgVkFYc3RhdGlvbnMsIGJ1dCBjYW4gYWxzbyBiZSB1c2VkIG9uIGFueSBzdGFuZGFyZCBSUzIzMiB3aXRoIGFuCiAqIGFkYXB0b3IpLgogKgogKiBESVNDTEFJTUVSOiBUaGlzIHdvcmtzIGZvciBfbWVfLiBJZiB5b3UgYnJlYWsgYW55dGhpbmcgYnkgdXNpbmcgdGhlCiAqIGluZm9ybWF0aW9uIGdpdmVuIGJlbG93LCBJIHdpbGwgX25vdF8gYmUgbGlhYmxlIQogKgogKiBSSjEwIHBpbm91dDoJCVRvIERFOToJCU9yIERCMjU6CiAqCTEgLSBSeEQgPC0tLS0+CVBpbiAzIChUeEQpIDwtPglQaW4gMiAoVHhEKQogKgkyIC0gR05EIDwtLS0tPglQaW4gNSAoR05EKSA8LT4JUGluIDcgKEdORCkKICoJNCAtIFR4RCA8LS0tLT4JUGluIDIgKFJ4RCkgPC0+CVBpbiAzIChSeEQpCiAqCTMgLSArMTJWIChmcm9tIEhERCBkcml2ZSBjb25uZWN0b3IpLCBET04nVCBjb25uZWN0IHRvIERFOSBvciBEQjI1ISEhCiAqCiAqIFBpbiBudW1iZXJzIGZvciBERTkgYW5kIERCMjUgYXJlIG5vdGVkIG9uIHRoZSBwbHVnIChxdWl0ZSBzbWFsbDopLiBGb3IKICogUkoxMCwgaXQncyBsaWtlIHRoaXM6CiAqCiAqICAgICAgX189X18JSG9sZCB0aGUgcGx1ZyBpbiBmcm9udCBvZiB5b3UsIGNhYmxlIGRvd253YXJkcywKICogICAgIC9fX18vfAlub3NlIGlzIGhpZGRlbiBiZWhpbmQgdGhlIHBsdWcuIE5vdywgcGluIDEgaXMgYXQKICogICAgfDEyMzR8fAl0aGUgbGVmdCBzaWRlLCBwaW4gNCBhdCB0aGUgcmlnaHQgYW5kIDIgYW5kIDMgYXJlCiAqICAgIHxJSUlJfHwJaW4gYmV0d2Vlbiwgb2YgY291cnNlOikKICogICAgfCAgICB8fAogKiAgICB8X19fX3wvCiAqICAgICAgfHwJU28gdGhlIGFkYXB0b3IgY29uc2lzdHMgb2YgdGhyZWUgY29ubmVjdGVkIGNhYmxlcwogKiAgICAgIHx8CWZvciBkYXRhIHRyYW5zbWlzc2lvbiAoUnhEIGFuZCBUeEQpIGFuZCBzaWduYWwgZ3JvdW5kLgogKgkJQWRkaXRpb25hbGx5LCB5b3UgaGF2ZSB0byBnZXQgKzEyViBmcm9tIHNvbWV3aGVyZS4KICogTW9zdCBlYXNpbHksIHlvdSdsbCBnZXQgdGhhdCBmcm9tIGEgZmxvcHB5IG9yIEhERCBwb3dlciBjb25uZWN0b3IuCiAqIEl0J3MgdGhlIHllbGxvdyBjYWJsZSB0aGVyZSAoYmxhY2sgaXMgZ3JvdW5kIGFuZCByZWQgaXMgKzVWKS4KICoKICogVGhlIGtleWJvYXJkIGFuZCBhbGwgdGhlIGNvbW1hbmRzIGl0IHVuZGVyc3RhbmRzIGFyZSBkb2N1bWVudGVkIGluCiAqICJWQ0IwMiBWaWRlbyBTdWJzeXN0ZW0gLSBUZWNobmljYWwgTWFudWFsIiwgRUstMTA0QUEtVE0tMDAxLiBUaGlzCiAqIGRvY3VtZW50IGlzIExLMjAxIHNwZWNpZmljLCBidXQgTEs0MDEgaXMgbW9zdGx5IGNvbXBhdGlibGUuIEl0IGNvbWVzCiAqIHVwIGluIExLMjAxIG1vZGUgYW5kIGRvZXNuJ3QgcmVwb3J0IGFueSBvZiB0aGUgYWRkaXRpb25hbCBrZXlzIGl0CiAqIGhhcy4gVGhlc2UgbmVlZCB0byBiZSBzd2l0Y2hlZCBvbiB3aXRoIHRoZSBMS19DTURfRU5BQkxFX0xLNDAxCiAqIGNvbW1hbmQuIFlvdSdsbCBmaW5kIHRoaXMgZG9jdW1lbnQgKHNjYW5uZWQgLnBkZiBmaWxlKSBvbiBNQU5YLAogKiBhIHNlYXJjaCBlbmdpbmUgc3BlY2lmaWMgdG8gREVDIGRvY3VtZW50YXRpb24uIFRyeQogKiBodHRwOi8vd3d3LnZ0MTAwLm5ldC9tYW54L2RldGFpbHM/cG49RUstMTA0QUEtVE0tMDAxO2lkPTIxO2NwPTEKICovCgovKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3IFVTQQogKgogKiBTaG91bGQgeW91IG5lZWQgdG8gY29udGFjdCBtZSwgdGhlIGF1dGhvciwgeW91IGNhbiBkbyBzbyBlaXRoZXIgYnkKICogZW1haWwgb3IgYnkgcGFwZXIgbWFpbDoKICogSmFuLUJlbmVkaWN0IEdsYXcsIExpbGllbnN0cmHfZSAxNiwgMzM3OTAgSPZyc3RlIChuZWFyIEhhbGxlL1dlc3RmLiksCiAqIEdlcm1hbnkuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2lucHV0Lmg+CiNpbmNsdWRlIDxsaW51eC9zZXJpby5oPgojaW5jbHVkZSA8bGludXgvd29ya3F1ZXVlLmg+CgojZGVmaW5lIERSSVZFUl9ERVNDCSJMSyBrZXlib2FyZCBkcml2ZXIiCgpNT0RVTEVfQVVUSE9SICgiSmFuLUJlbmVkaWN0IEdsYXcgPGpiZ2xhd0BsdWctb3dsLmRlPiIpOwpNT0RVTEVfREVTQ1JJUFRJT04gKERSSVZFUl9ERVNDKTsKTU9EVUxFX0xJQ0VOU0UgKCJHUEwiKTsKCi8qCiAqIEtub3duIHBhcmFtZXRlcnM6CiAqCWJlbGxfdm9sdW1lCiAqCWtleWNsaWNrX3ZvbHVtZQogKgljdHJsY2xpY2tfdm9sdW1lCiAqCiAqIFBsZWFzZSBub3RpY2UgdGhhdCB0aGVyZSdzIG5vdCB5ZXQgYW4gQVBJIHRvIHNldCB0aGVzZSBhdCBydW50aW1lLgogKi8Kc3RhdGljIGludCBiZWxsX3ZvbHVtZSA9IDEwMDsgLyogJSAqLwptb2R1bGVfcGFyYW0gKGJlbGxfdm9sdW1lLCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDIChiZWxsX3ZvbHVtZSwgIkJlbGwgdm9sdW1lIChpbiAlKS4gZGVmYXVsdCBpcyAxMDAlIik7CgpzdGF0aWMgaW50IGtleWNsaWNrX3ZvbHVtZSA9IDEwMDsgLyogJSAqLwptb2R1bGVfcGFyYW0gKGtleWNsaWNrX3ZvbHVtZSwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyAoa2V5Y2xpY2tfdm9sdW1lLCAiS2V5Y2xpY2sgdm9sdW1lIChpbiAlKSwgZGVmYXVsdCBpcyAxMDAlIik7CgpzdGF0aWMgaW50IGN0cmxjbGlja192b2x1bWUgPSAxMDA7IC8qICUgKi8KbW9kdWxlX3BhcmFtIChjdHJsY2xpY2tfdm9sdW1lLCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDIChjdHJsY2xpY2tfdm9sdW1lLCAiQ3RybGNsaWNrIHZvbHVtZSAoaW4gJSksIGRlZmF1bHQgaXMgMTAwJSIpOwoKc3RhdGljIGludCBsazIwMV9jb21wb3NlX2lzX2FsdCA9IDA7Cm1vZHVsZV9wYXJhbSAobGsyMDFfY29tcG9zZV9pc19hbHQsIGludCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MgKGxrMjAxX2NvbXBvc2VfaXNfYWx0LCAiSWYgc2V0IG5vbi16ZXJvLCBMSzIwMScgQ29tcG9zZSBrZXkgIgoJCSJ3aWxsIGFjdCBhcyBhbiBBbHQga2V5Iik7CgoKCiN1bmRlZiBMS0tCRF9ERUJVRwojaWZkZWYgTEtLQkRfREVCVUcKI2RlZmluZSBEQkcoeC4uLikgcHJpbnRrICh4KQojZWxzZQojZGVmaW5lIERCRyh4Li4uKSBkbyB7fSB3aGlsZSAoMCkKI2VuZGlmCgovKiBMRUQgY29udHJvbCAqLwojZGVmaW5lIExLX0xFRF9XQUlUCQkweDgxCiNkZWZpbmUgTEtfTEVEX0NPTVBPU0UJCTB4ODIKI2RlZmluZSBMS19MRURfU0hJRlRMT0NLCTB4ODQKI2RlZmluZSBMS19MRURfU0NST0xMTE9DSwkweDg4CiNkZWZpbmUgTEtfQ01EX0xFRF9PTgkJMHgxMwojZGVmaW5lIExLX0NNRF9MRURfT0ZGCQkweDExCgovKiBNb2RlIGNvbnRyb2wgKi8KI2RlZmluZSBMS19NT0RFX0RPV04JCTB4ODAKI2RlZmluZSBMS19NT0RFX0FVVE9ET1dOCTB4ODIKI2RlZmluZSBMS19NT0RFX1VQRE9XTgkJMHg4NgojZGVmaW5lIExLX0NNRF9TRVRfTU9ERShtb2RlLGRpdikJKChtb2RlKSB8ICgoZGl2KSA8PCAzKSkKCi8qIE1pc2MgY29tbWFuZHMgKi8KI2RlZmluZSBMS19DTURfRU5BQkxFX0tFWUNMSUNLCTB4MWIKI2RlZmluZSBMS19DTURfRElTQUJMRV9LRVlDTElDSwkweDk5CiNkZWZpbmUgTEtfQ01EX0RJU0FCTEVfQkVMTAkweGExCiNkZWZpbmUgTEtfQ01EX1NPVU5EX0JFTEwJMHhhNwojZGVmaW5lIExLX0NNRF9FTkFCTEVfQkVMTAkweDIzCiNkZWZpbmUgTEtfQ01EX0RJU0FCTEVfQ1RSQ0xJQ0sJMHhiOQojZGVmaW5lIExLX0NNRF9FTkFCTEVfQ1RSQ0xJQ0sJMHhiYgojZGVmaW5lIExLX0NNRF9TRVRfREVGQVVMVFMJMHhkMwojZGVmaW5lIExLX0NNRF9QT1dFUkNZQ0xFX1JFU0VUCTB4ZmQKI2RlZmluZSBMS19DTURfRU5BQkxFX0xLNDAxCTB4ZTkKI2RlZmluZSBMS19DTURfUkVRVUVTVF9JRAkweGFiCgovKiBNaXNjIHJlc3BvbnNlcyBmcm9tIGtleWJvYXJkICovCiNkZWZpbmUgTEtfU1RVQ0tfS0VZCQkweDNkCiNkZWZpbmUgTEtfU0VMRlRFU1RfRkFJTEVECTB4M2UKI2RlZmluZSBMS19BTExfS0VZU19VUAkJMHhiMwojZGVmaW5lIExLX01FVFJPTk9NRQkJMHhiNAojZGVmaW5lIExLX09VVFBVVF9FUlJPUgkJMHhiNQojZGVmaW5lIExLX0lOUFVUX0VSUk9SCQkweGI2CiNkZWZpbmUgTEtfS0JEX0xPQ0tFRAkJMHhiNwojZGVmaW5lIExLX0tCRF9URVNUX01PREVfQUNLCTB4YjgKI2RlZmluZSBMS19QUkVGSVhfS0VZX0RPV04JMHhiOQojZGVmaW5lIExLX01PREVfQ0hBTkdFX0FDSwkweGJhCiNkZWZpbmUgTEtfUkVTUE9OU0VfUkVTRVJWRUQJMHhiYgoKI2RlZmluZSBMS19OVU1fS0VZQ09ERVMJCTI1NgojZGVmaW5lIExLX05VTV9JR05PUkVfQllURVMJNgp0eXBlZGVmIHVfaW50MTZfdCBsa19rZXljb2RlX3Q7CgoKCnN0YXRpYyBsa19rZXljb2RlX3QgbGtrYmRfa2V5Y29kZVtMS19OVU1fS0VZQ09ERVNdID0gewoJWzB4NTZdID0gS0VZX0YxLAoJWzB4NTddID0gS0VZX0YyLAoJWzB4NThdID0gS0VZX0YzLAoJWzB4NTldID0gS0VZX0Y0LAoJWzB4NWFdID0gS0VZX0Y1LAoJWzB4NjRdID0gS0VZX0Y2LAoJWzB4NjVdID0gS0VZX0Y3LAoJWzB4NjZdID0gS0VZX0Y4LAoJWzB4NjddID0gS0VZX0Y5LAoJWzB4NjhdID0gS0VZX0YxMCwKCVsweDcxXSA9IEtFWV9GMTEsCglbMHg3Ml0gPSBLRVlfRjEyLAoJWzB4NzNdID0gS0VZX0YxMywKCVsweDc0XSA9IEtFWV9GMTQsCglbMHg3Y10gPSBLRVlfRjE1LAoJWzB4N2RdID0gS0VZX0YxNiwKCVsweDgwXSA9IEtFWV9GMTcsCglbMHg4MV0gPSBLRVlfRjE4LAoJWzB4ODJdID0gS0VZX0YxOSwKCVsweDgzXSA9IEtFWV9GMjAsCglbMHg4YV0gPSBLRVlfRklORCwKCVsweDhiXSA9IEtFWV9JTlNFUlQsCglbMHg4Y10gPSBLRVlfREVMRVRFLAoJWzB4OGRdID0gS0VZX1NFTEVDVCwKCVsweDhlXSA9IEtFWV9QQUdFVVAsCglbMHg4Zl0gPSBLRVlfUEFHRURPV04sCglbMHg5Ml0gPSBLRVlfS1AwLAoJWzB4OTRdID0gS0VZX0tQRE9ULAoJWzB4OTVdID0gS0VZX0tQRU5URVIsCglbMHg5Nl0gPSBLRVlfS1AxLAoJWzB4OTddID0gS0VZX0tQMiwKCVsweDk4XSA9IEtFWV9LUDMsCglbMHg5OV0gPSBLRVlfS1A0LAoJWzB4OWFdID0gS0VZX0tQNSwKCVsweDliXSA9IEtFWV9LUDYsCglbMHg5Y10gPSBLRVlfS1BDT01NQSwKCVsweDlkXSA9IEtFWV9LUDcsCglbMHg5ZV0gPSBLRVlfS1A4LAoJWzB4OWZdID0gS0VZX0tQOSwKCVsweGEwXSA9IEtFWV9LUE1JTlVTLAoJWzB4YTFdID0gS0VZX1BST0cxLAoJWzB4YTJdID0gS0VZX1BST0cyLAoJWzB4YTNdID0gS0VZX1BST0czLAoJWzB4YTRdID0gS0VZX1BST0c0LAoJWzB4YTddID0gS0VZX0xFRlQsCglbMHhhOF0gPSBLRVlfUklHSFQsCglbMHhhOV0gPSBLRVlfRE9XTiwKCVsweGFhXSA9IEtFWV9VUCwKCVsweGFiXSA9IEtFWV9SSUdIVFNISUZULAoJWzB4YWNdID0gS0VZX0xFRlRBTFQsCglbMHhhZF0gPSBLRVlfQ09NUE9TRSwgLyogUmlnaHQgQ29tcG9zZSwgdGhhdCBpcy4gKi8KCVsweGFlXSA9IEtFWV9MRUZUU0hJRlQsIC8qIFNhbWUgYXMgS0VZX1JJR0hUU0hJRlQgb24gTEsyMDEgKi8KCVsweGFmXSA9IEtFWV9MRUZUQ1RSTCwKCVsweGIwXSA9IEtFWV9DQVBTTE9DSywKCVsweGIxXSA9IEtFWV9DT01QT1NFLCAvKiBMZWZ0IENvbXBvc2UsIHRoYXQgaXMuICovCglbMHhiMl0gPSBLRVlfUklHSFRBTFQsCglbMHhiY10gPSBLRVlfQkFDS1NQQUNFLAoJWzB4YmRdID0gS0VZX0VOVEVSLAoJWzB4YmVdID0gS0VZX1RBQiwKCVsweGJmXSA9IEtFWV9FU0MsCglbMHhjMF0gPSBLRVlfMSwKCVsweGMxXSA9IEtFWV9RLAoJWzB4YzJdID0gS0VZX0EsCglbMHhjM10gPSBLRVlfWiwKCVsweGM1XSA9IEtFWV8yLAoJWzB4YzZdID0gS0VZX1csCglbMHhjN10gPSBLRVlfUywKCVsweGM4XSA9IEtFWV9YLAoJWzB4YzldID0gS0VZXzEwMk5ELAoJWzB4Y2JdID0gS0VZXzMsCglbMHhjY10gPSBLRVlfRSwKCVsweGNkXSA9IEtFWV9ELAoJWzB4Y2VdID0gS0VZX0MsCglbMHhkMF0gPSBLRVlfNCwKCVsweGQxXSA9IEtFWV9SLAoJWzB4ZDJdID0gS0VZX0YsCglbMHhkM10gPSBLRVlfViwKCVsweGQ0XSA9IEtFWV9TUEFDRSwKCVsweGQ2XSA9IEtFWV81LAoJWzB4ZDddID0gS0VZX1QsCglbMHhkOF0gPSBLRVlfRywKCVsweGQ5XSA9IEtFWV9CLAoJWzB4ZGJdID0gS0VZXzYsCglbMHhkY10gPSBLRVlfWSwKCVsweGRkXSA9IEtFWV9ILAoJWzB4ZGVdID0gS0VZX04sCglbMHhlMF0gPSBLRVlfNywKCVsweGUxXSA9IEtFWV9VLAoJWzB4ZTJdID0gS0VZX0osCglbMHhlM10gPSBLRVlfTSwKCVsweGU1XSA9IEtFWV84LAoJWzB4ZTZdID0gS0VZX0ksCglbMHhlN10gPSBLRVlfSywKCVsweGU4XSA9IEtFWV9DT01NQSwKCVsweGVhXSA9IEtFWV85LAoJWzB4ZWJdID0gS0VZX08sCglbMHhlY10gPSBLRVlfTCwKCVsweGVkXSA9IEtFWV9ET1QsCglbMHhlZl0gPSBLRVlfMCwKCVsweGYwXSA9IEtFWV9QLAoJWzB4ZjJdID0gS0VZX1NFTUlDT0xPTiwKCVsweGYzXSA9IEtFWV9TTEFTSCwKCVsweGY1XSA9IEtFWV9FUVVBTCwKCVsweGY2XSA9IEtFWV9SSUdIVEJSQUNFLAoJWzB4ZjddID0gS0VZX0JBQ0tTTEFTSCwKCVsweGY5XSA9IEtFWV9NSU5VUywKCVsweGZhXSA9IEtFWV9MRUZUQlJBQ0UsCglbMHhmYl0gPSBLRVlfQVBPU1RST1BIRSwKfTsKCiNkZWZpbmUgQ0hFQ0tfTEVEKExFRCwgQklUUykgZG8gewkJXAoJaWYgKHRlc3RfYml0IChMRUQsIGxrLT5kZXYubGVkKSkJXAoJCWxlZHNfb24gfD0gQklUUzsJCVwKCWVsc2UJCQkJCVwKCQlsZWRzX29mZiB8PSBCSVRTOwkJXAoJfSB3aGlsZSAoMCkKCi8qCiAqIFBlci1rZXlib2FyZCBkYXRhCiAqLwpzdHJ1Y3QgbGtrYmQgewoJbGtfa2V5Y29kZV90IGtleWNvZGVbTEtfTlVNX0tFWUNPREVTXTsKCWludCBpZ25vcmVfYnl0ZXM7Cgl1bnNpZ25lZCBjaGFyIGlkW0xLX05VTV9JR05PUkVfQllURVNdOwoJc3RydWN0IGlucHV0X2RldiBkZXY7CglzdHJ1Y3Qgc2VyaW8gKnNlcmlvOwoJc3RydWN0IHdvcmtfc3RydWN0IHRxOwoJY2hhciBuYW1lWzY0XTsKCWNoYXIgcGh5c1szMl07CgljaGFyIHR5cGU7CglpbnQgYmVsbF92b2x1bWU7CglpbnQga2V5Y2xpY2tfdm9sdW1lOwoJaW50IGN0cmxjbGlja192b2x1bWU7Cn07CgovKgogKiBDYWxjdWxhdGUgdm9sdW1lIHBhcmFtZXRlciBieXRlIGZvciBhIGdpdmVuIHZvbHVtZS4KICovCnN0YXRpYyB1bnNpZ25lZCBjaGFyCnZvbHVtZV90b19odyAoaW50IHZvbHVtZV9wZXJjZW50KQp7Cgl1bnNpZ25lZCBjaGFyIHJldCA9IDA7CgoJaWYgKHZvbHVtZV9wZXJjZW50IDwgMCkKCQl2b2x1bWVfcGVyY2VudCA9IDA7CglpZiAodm9sdW1lX3BlcmNlbnQgPiAxMDApCgkJdm9sdW1lX3BlcmNlbnQgPSAxMDA7CgoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDApCgkJcmV0ID0gNzsKCWlmICh2b2x1bWVfcGVyY2VudCA+PSAxMykJLyogMTIuNSAqLwoJCXJldCA9IDY7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gMjUpCgkJcmV0ID0gNTsKCWlmICh2b2x1bWVfcGVyY2VudCA+PSAzOCkJLyogMzcuNSAqLwoJCXJldCA9IDQ7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gNTApCgkJcmV0ID0gMzsKCWlmICh2b2x1bWVfcGVyY2VudCA+PSA2MykJLyogNjIuNSAqLwoJCXJldCA9IDI7CQkvKiBUaGlzIGlzIHRoZSBkZWZhdWx0IHZvbHVtZSAqLwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDc1KQoJCXJldCA9IDE7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gODgpCS8qIDg3LjUgKi8KCQlyZXQgPSAwOwoKCXJldCB8PSAweDgwOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyB2b2lkCmxra2JkX2RldGVjdGlvbl9kb25lIChzdHJ1Y3QgbGtrYmQgKmxrKQp7CglpbnQgaTsKCgkvKgoJICogUmVzZXQgc2V0dGluZyBmb3IgQ29tcG9zZSBrZXkuIExldCBDb21wb3NlIGJlIEtFWV9DT01QT1NFLgoJICovCglsay0+a2V5Y29kZVsweGIxXSA9IEtFWV9DT01QT1NFOwoKCS8qCgkgKiBQcmludCBrZXlib2FyZCBuYW1lIGFuZCBtb2RpZnkgQ29tcG9zZT1BbHQgb24gdXNlcidzIHJlcXVlc3QuCgkgKi8KCXN3aXRjaCAobGstPmlkWzRdKSB7CgkJY2FzZSAxOgoJCQlzcHJpbnRmIChsay0+bmFtZSwgIkRFQyBMSzIwMSBrZXlib2FyZCIpOwoKCQkJaWYgKGxrMjAxX2NvbXBvc2VfaXNfYWx0KQoJCQkJbGstPmtleWNvZGVbMHhiMV0gPSBLRVlfTEVGVEFMVDsKCQkJYnJlYWs7CgoJCWNhc2UgMjoKCQkJc3ByaW50ZiAobGstPm5hbWUsICJERUMgTEs0MDEga2V5Ym9hcmQiKTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCXNwcmludGYgKGxrLT5uYW1lLCAiVW5rbm93biBERUMga2V5Ym9hcmQiKTsKCQkJcHJpbnRrIChLRVJOX0VSUiAibGtrYmQ6IGtleWJvYXJkIG9uICVzIGlzIHVua25vd24sICIKCQkJCQkicGxlYXNlIHJlcG9ydCB0byBKYW4tQmVuZWRpY3QgR2xhdyAiCgkJCQkJIjxqYmdsYXdAbHVnLW93bC5kZT5cbiIsIGxrLT5waHlzKTsKCQkJcHJpbnRrIChLRVJOX0VSUiAibGtrYmQ6IGtleWJvYXJkIElEJ2VkIGFzOiIpOwoJCQlmb3IgKGkgPSAwOyBpIDwgTEtfTlVNX0lHTk9SRV9CWVRFUzsgaSsrKQoJCQkJcHJpbnRrICgiIDB4JTAyeCIsIGxrLT5pZFtpXSk7CgkJCXByaW50ayAoIlxuIik7CgkJCWJyZWFrOwoJfQoJcHJpbnRrIChLRVJOX0lORk8gImxra2JkOiBrZXlib2FyZCBvbiAlcyBpZGVudGlmaWVkIGFzOiAlc1xuIiwKCQkJbGstPnBoeXMsIGxrLT5uYW1lKTsKCgkvKgoJICogUmVwb3J0IGVycm9ycyBkdXJpbmcga2V5Ym9hcmQgYm9vdC11cC4KCSAqLwoJc3dpdGNoIChsay0+aWRbMl0pIHsKCQljYXNlIDB4MDA6CgkJCS8qIEFsbCBva2F5ICovCgkJCWJyZWFrOwoKCQljYXNlIExLX1NUVUNLX0tFWToKCQkJcHJpbnRrIChLRVJOX0VSUiAibGtrYmQ6IFN0dWNrIGtleSBvbiBrZXlib2FyZCBhdCAiCgkJCQkJIiVzXG4iLCBsay0+cGh5cyk7CgkJCWJyZWFrOwoKCQljYXNlIExLX1NFTEZURVNUX0ZBSUxFRDoKCQkJcHJpbnRrIChLRVJOX0VSUiAibGtrYmQ6IFNlbGZ0ZXN0IGZhaWxlZCBvbiBrZXlib2FyZCAiCgkJCQkJImF0ICVzLCBrZXlib2FyZCBtYXkgbm90IHdvcmsgIgoJCQkJCSJwcm9wZXJseVxuIiwgbGstPnBoeXMpOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJcHJpbnRrIChLRVJOX0VSUiAibGtrYmQ6IFVua25vd24gZXJyb3IgJTAyeCBvbiAiCgkJCQkJImtleWJvYXJkIGF0ICVzXG4iLCBsay0+aWRbMl0sCgkJCQkJbGstPnBoeXMpOwoJCQlicmVhazsKCX0KCgkvKgoJICogVHJ5IHRvIGhpbnQgdXNlciBpZiB0aGVyZSdzIGEgc3R1Y2sga2V5LgoJICovCglpZiAobGstPmlkWzJdID09IExLX1NUVUNLX0tFWSAmJiBsay0+aWRbM10gIT0gMCkKCQlwcmludGsgKEtFUk5fRVJSICJTY2FuY29kZSBvZiBzdHVjayBrZXkgaXMgMHglMDJ4LCBrZXljb2RlICIKCQkJCSJpcyAweCUwNHhcbiIsIGxrLT5pZFszXSwKCQkJCWxrLT5rZXljb2RlW2xrLT5pZFszXV0pOwoKCXJldHVybjsKfQoKLyoKICogbGtrYmRfaW50ZXJydXB0KCkgaXMgY2FsbGVkIGJ5IHRoZSBsb3cgbGV2ZWwgZHJpdmVyIHdoZW4gYSBjaGFyYWN0ZXIKICogaXMgcmVjZWl2ZWQuCiAqLwpzdGF0aWMgaXJxcmV0dXJuX3QKbGtrYmRfaW50ZXJydXB0IChzdHJ1Y3Qgc2VyaW8gKnNlcmlvLCB1bnNpZ25lZCBjaGFyIGRhdGEsIHVuc2lnbmVkIGludCBmbGFncywKCQlzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IGxra2JkICpsayA9IHNlcmlvX2dldF9kcnZkYXRhIChzZXJpbyk7CglpbnQgaTsKCglEQkcgKEtFUk5fSU5GTyAiR290IGJ5dGUgMHglMDJ4XG4iLCBkYXRhKTsKCglpZiAobGstPmlnbm9yZV9ieXRlcyA+IDApIHsKCQlEQkcgKEtFUk5fSU5GTyAiSWdub3JpbmcgYSBieXRlIG9uICVzXG4iLAoJCQkJbGstPm5hbWUpOwoJCWxrLT5pZFtMS19OVU1fSUdOT1JFX0JZVEVTIC0gbGstPmlnbm9yZV9ieXRlcy0tXSA9IGRhdGE7CgoJCWlmIChsay0+aWdub3JlX2J5dGVzID09IDApCgkJCWxra2JkX2RldGVjdGlvbl9kb25lIChsayk7CgoJCXJldHVybiBJUlFfSEFORExFRDsKCX0KCglzd2l0Y2ggKGRhdGEpIHsKCQljYXNlIExLX0FMTF9LRVlTX1VQOgoJCQlpbnB1dF9yZWdzICgmbGstPmRldiwgcmVncyk7CgkJCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFIChsa2tiZF9rZXljb2RlKTsgaSsrKQoJCQkJaWYgKGxrLT5rZXljb2RlW2ldICE9IEtFWV9SRVNFUlZFRCkKCQkJCQlpbnB1dF9yZXBvcnRfa2V5ICgmbGstPmRldiwgbGstPmtleWNvZGVbaV0sIDApOwoJCQlpbnB1dF9zeW5jICgmbGstPmRldik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfTUVUUk9OT01FOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX01FVFJPTk9NRSBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX09VVFBVVF9FUlJPUjoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19PVVRQVVRfRVJST1IgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19JTlBVVF9FUlJPUjoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19JTlBVVF9FUlJPUiBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX0tCRF9MT0NLRUQ6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfS0JEX0xPQ0tFRCBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX0tCRF9URVNUX01PREVfQUNLOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX0tCRF9URVNUX01PREVfQUNLIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfUFJFRklYX0tFWV9ET1dOOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX1BSRUZJWF9LRVlfRE9XTiBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX01PREVfQ0hBTkdFX0FDSzoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19NT0RFX0NIQU5HRV9BQ0sgYW5kIGlnbm9yZWQgIgoJCQkJCSJpdCBwcm9wZXJseS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfUkVTUE9OU0VfUkVTRVJWRUQ6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfUkVTUE9OU0VfUkVTRVJWRUQgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSAweDAxOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IDB4MDEsIHNjaGVkdWxpbmcgcmUtaW5pdGlhbGl6YXRpb25cbiIpOwoJCQlsay0+aWdub3JlX2J5dGVzID0gTEtfTlVNX0lHTk9SRV9CWVRFUzsKCQkJbGstPmlkW0xLX05VTV9JR05PUkVfQllURVMgLSBsay0+aWdub3JlX2J5dGVzLS1dID0gZGF0YTsKCQkJc2NoZWR1bGVfd29yayAoJmxrLT50cSk7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlpZiAobGstPmtleWNvZGVbZGF0YV0gIT0gS0VZX1JFU0VSVkVEKSB7CgkJCQlpbnB1dF9yZWdzICgmbGstPmRldiwgcmVncyk7CgkJCQlpZiAoIXRlc3RfYml0IChsay0+a2V5Y29kZVtkYXRhXSwgbGstPmRldi5rZXkpKQoJCQkJCWlucHV0X3JlcG9ydF9rZXkgKCZsay0+ZGV2LCBsay0+a2V5Y29kZVtkYXRhXSwgMSk7CgkJCQllbHNlCgkJCQkJaW5wdXRfcmVwb3J0X2tleSAoJmxrLT5kZXYsIGxrLT5rZXljb2RlW2RhdGFdLCAwKTsKCQkJCWlucHV0X3N5bmMgKCZsay0+ZGV2KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRrIChLRVJOX1dBUk5JTkcgIiVzOiBVbmtub3duIGtleSB3aXRoICIKCQkJCQkJInNjYW5jb2RlIDB4JTAyeCBvbiAlcy5cbiIsCgkJCQkJCV9fRklMRV9fLCBkYXRhLCBsay0+bmFtZSk7Cgl9CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgovKgogKiBsa2tiZF9ldmVudCgpIGhhbmRsZXMgZXZlbnRzIGZyb20gdGhlIGlucHV0IG1vZHVsZS4KICovCnN0YXRpYyBpbnQKbGtrYmRfZXZlbnQgKHN0cnVjdCBpbnB1dF9kZXYgKmRldiwgdW5zaWduZWQgaW50IHR5cGUsIHVuc2lnbmVkIGludCBjb2RlLAoJCWludCB2YWx1ZSkKewoJc3RydWN0IGxra2JkICpsayA9IGRldi0+cHJpdmF0ZTsKCXVuc2lnbmVkIGNoYXIgbGVkc19vbiA9IDA7Cgl1bnNpZ25lZCBjaGFyIGxlZHNfb2ZmID0gMDsKCglzd2l0Y2ggKHR5cGUpIHsKCQljYXNlIEVWX0xFRDoKCQkJQ0hFQ0tfTEVEIChMRURfQ0FQU0wsIExLX0xFRF9TSElGVExPQ0spOwoJCQlDSEVDS19MRUQgKExFRF9DT01QT1NFLCBMS19MRURfQ09NUE9TRSk7CgkJCUNIRUNLX0xFRCAoTEVEX1NDUk9MTEwsIExLX0xFRF9TQ1JPTExMT0NLKTsKCQkJQ0hFQ0tfTEVEIChMRURfU0xFRVAsIExLX0xFRF9XQUlUKTsKCQkJaWYgKGxlZHNfb24gIT0gMCkgewoJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfTEVEX09OKTsKCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgbGVkc19vbik7CgkJCX0KCQkJaWYgKGxlZHNfb2ZmICE9IDApIHsKCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0xFRF9PRkYpOwoJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBsZWRzX29mZik7CgkJCX0KCQkJcmV0dXJuIDA7CgoJCWNhc2UgRVZfU05EOgoJCQlzd2l0Y2ggKGNvZGUpIHsKCQkJCWNhc2UgU05EX0NMSUNLOgoJCQkJCWlmICh2YWx1ZSA9PSAwKSB7CgkJCQkJCURCRyAoIiVzOiBEZWFjdGl2YXRpbmcga2V5IGNsaWNrc1xuIiwgX19GVU5DVElPTl9fKTsKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRElTQUJMRV9LRVlDTElDSyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0RJU0FCTEVfQ1RSQ0xJQ0spOwoJCQkJCX0gZWxzZSB7CgkJCQkJCURCRyAoIiVzOiBBY3RpdmF0aW5nIGtleSBjbGlja3NcbiIsIF9fRlVOQ1RJT05fXyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9LRVlDTElDSyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+a2V5Y2xpY2tfdm9sdW1lKSk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9DVFJDTElDSyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+Y3RybGNsaWNrX3ZvbHVtZSkpOwoJCQkJCX0KCQkJCQlyZXR1cm4gMDsKCgkJCQljYXNlIFNORF9CRUxMOgoJCQkJCWlmICh2YWx1ZSAhPSAwKQoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9TT1VORF9CRUxMKTsKCgkJCQkJcmV0dXJuIDA7CgkJCX0KCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCXByaW50ayAoS0VSTl9FUlIgIiVzICgpOiBHb3QgdW5rbm93biB0eXBlICVkLCBjb2RlICVkLCB2YWx1ZSAlZFxuIiwKCQkJCQlfX0ZVTkNUSU9OX18sIHR5cGUsIGNvZGUsIHZhbHVlKTsKCX0KCglyZXR1cm4gLTE7Cn0KCi8qCiAqIGxra2JkX3JlaW5pdCgpIHNldHMgbGVkcyBhbmQgYmVlcHMgdG8gYSBzdGF0ZSB0aGUgY29tcHV0ZXIgcmVtZW1iZXJzIHRoZXkKICogd2VyZSBpbi4KICovCnN0YXRpYyB2b2lkCmxra2JkX3JlaW5pdCAodm9pZCAqZGF0YSkKewoJc3RydWN0IGxra2JkICpsayA9IGRhdGE7CglpbnQgZGl2aXNpb247Cgl1bnNpZ25lZCBjaGFyIGxlZHNfb24gPSAwOwoJdW5zaWduZWQgY2hhciBsZWRzX29mZiA9IDA7CgoJLyogQXNrIGZvciBJRCAqLwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfUkVRVUVTVF9JRCk7CgoJLyogUmVzZXQgcGFyYW1ldGVycyAqLwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfU0VUX0RFRkFVTFRTKTsKCgkvKiBTZXQgTEVEcyAqLwoJQ0hFQ0tfTEVEIChMRURfQ0FQU0wsIExLX0xFRF9TSElGVExPQ0spOwoJQ0hFQ0tfTEVEIChMRURfQ09NUE9TRSwgTEtfTEVEX0NPTVBPU0UpOwoJQ0hFQ0tfTEVEIChMRURfU0NST0xMTCwgTEtfTEVEX1NDUk9MTExPQ0spOwoJQ0hFQ0tfTEVEIChMRURfU0xFRVAsIExLX0xFRF9XQUlUKTsKCWlmIChsZWRzX29uICE9IDApIHsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9MRURfT04pOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgbGVkc19vbik7Cgl9CglpZiAobGVkc19vZmYgIT0gMCkgewoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0xFRF9PRkYpOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgbGVkc19vZmYpOwoJfQoKCS8qCgkgKiBUcnkgdG8gYWN0aXZhdGUgZXh0ZW5kZWQgTEs0MDEgbW9kZS4gVGhpcyBjb21tYW5kIHdpbGwKCSAqIG9ubHkgd29yayB3aXRoIGEgTEs0MDEga2V5Ym9hcmQgYW5kIGdyYW50cyBhY2Nlc3MgdG8KCSAqIExBbHQsIFJBbHQsIFJDb21wb3NlIGFuZCBSU2hpZnQuCgkgKi8KCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9MSzQwMSk7CgoJLyogU2V0IGFsbCBrZXlzIHRvIFVQRE9XTiBtb2RlICovCglmb3IgKGRpdmlzaW9uID0gMTsgZGl2aXNpb24gPD0gMTQ7IGRpdmlzaW9uKyspCgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfU0VUX01PREUgKExLX01PREVfVVBET1dOLAoJCQkJCWRpdmlzaW9uKSk7CgoJLyogRW5hYmxlIGJlbGwgYW5kIHNldCB2b2x1bWUgKi8KCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9CRUxMKTsKCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+YmVsbF92b2x1bWUpKTsKCgkvKiBFbmFibGUvZGlzYWJsZSBrZXljbGljayAoYW5kIHBvc3NpYmx5IHNldCB2b2x1bWUpICovCglpZiAodGVzdF9iaXQgKFNORF9DTElDSywgbGstPmRldi5zbmQpKSB7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRU5BQkxFX0tFWUNMSUNLKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIHZvbHVtZV90b19odyAobGstPmtleWNsaWNrX3ZvbHVtZSkpOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9DVFJDTElDSyk7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCB2b2x1bWVfdG9faHcgKGxrLT5jdHJsY2xpY2tfdm9sdW1lKSk7Cgl9IGVsc2UgewoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0RJU0FCTEVfS0VZQ0xJQ0spOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0RJU0FCTEVfQ1RSQ0xJQ0spOwoJfQoKCS8qIFNvdW5kIHRoZSBiZWxsIGlmIG5lZWRlZCAqLwoJaWYgKHRlc3RfYml0IChTTkRfQkVMTCwgbGstPmRldi5zbmQpKQoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX1NPVU5EX0JFTEwpOwp9CgovKgogKiBsa2tiZF9jb25uZWN0KCkgcHJvYmVzIGZvciBhIExLIGtleWJvYXJkIGFuZCBmaWxscyB0aGUgbmVjZXNzYXJ5IHN0cnVjdHVyZXMuCiAqLwpzdGF0aWMgaW50Cmxra2JkX2Nvbm5lY3QgKHN0cnVjdCBzZXJpbyAqc2VyaW8sIHN0cnVjdCBzZXJpb19kcml2ZXIgKmRydikKewoJc3RydWN0IGxra2JkICpsazsKCWludCBpOwoJaW50IGVycjsKCglpZiAoIShsayA9IGttYWxsb2MgKHNpemVvZiAoc3RydWN0IGxra2JkKSwgR0ZQX0tFUk5FTCkpKQoJCXJldHVybiAtRU5PTUVNOwoKCW1lbXNldCAobGssIDAsIHNpemVvZiAoc3RydWN0IGxra2JkKSk7CgoJaW5pdF9pbnB1dF9kZXYgKCZsay0+ZGV2KTsKCXNldF9iaXQgKEVWX0tFWSwgbGstPmRldi5ldmJpdCk7CglzZXRfYml0IChFVl9MRUQsIGxrLT5kZXYuZXZiaXQpOwoJc2V0X2JpdCAoRVZfU05ELCBsay0+ZGV2LmV2Yml0KTsKCXNldF9iaXQgKEVWX1JFUCwgbGstPmRldi5ldmJpdCk7CglzZXRfYml0IChMRURfQ0FQU0wsIGxrLT5kZXYubGVkYml0KTsKCXNldF9iaXQgKExFRF9TTEVFUCwgbGstPmRldi5sZWRiaXQpOwoJc2V0X2JpdCAoTEVEX0NPTVBPU0UsIGxrLT5kZXYubGVkYml0KTsKCXNldF9iaXQgKExFRF9TQ1JPTExMLCBsay0+ZGV2LmxlZGJpdCk7CglzZXRfYml0IChTTkRfQkVMTCwgbGstPmRldi5zbmRiaXQpOwoJc2V0X2JpdCAoU05EX0NMSUNLLCBsay0+ZGV2LnNuZGJpdCk7CgoJbGstPnNlcmlvID0gc2VyaW87CgoJSU5JVF9XT1JLICgmbGstPnRxLCBsa2tiZF9yZWluaXQsIGxrKTsKCglsay0+YmVsbF92b2x1bWUgPSBiZWxsX3ZvbHVtZTsKCWxrLT5rZXljbGlja192b2x1bWUgPSBrZXljbGlja192b2x1bWU7Cglsay0+Y3RybGNsaWNrX3ZvbHVtZSA9IGN0cmxjbGlja192b2x1bWU7CgoJbGstPmRldi5rZXljb2RlID0gbGstPmtleWNvZGU7Cglsay0+ZGV2LmtleWNvZGVzaXplID0gc2l6ZW9mIChsa19rZXljb2RlX3QpOwoJbGstPmRldi5rZXljb2RlbWF4ID0gTEtfTlVNX0tFWUNPREVTOwoKCWxrLT5kZXYuZXZlbnQgPSBsa2tiZF9ldmVudDsKCWxrLT5kZXYucHJpdmF0ZSA9IGxrOwoKCXNlcmlvX3NldF9kcnZkYXRhIChzZXJpbywgbGspOwoKCWVyciA9IHNlcmlvX29wZW4gKHNlcmlvLCBkcnYpOwoJaWYgKGVycikgewoJCXNlcmlvX3NldF9kcnZkYXRhIChzZXJpbywgTlVMTCk7CgkJa2ZyZWUgKGxrKTsKCQlyZXR1cm4gZXJyOwoJfQoKCXNwcmludGYgKGxrLT5uYW1lLCAiREVDIExLIGtleWJvYXJkIik7CglzcHJpbnRmIChsay0+cGh5cywgIiVzL2lucHV0MCIsIHNlcmlvLT5waHlzKTsKCgltZW1jcHkgKGxrLT5rZXljb2RlLCBsa2tiZF9rZXljb2RlLCBzaXplb2YgKGxrX2tleWNvZGVfdCkgKiBMS19OVU1fS0VZQ09ERVMpOwoJZm9yIChpID0gMDsgaSA8IExLX05VTV9LRVlDT0RFUzsgaSsrKQoJCXNldF9iaXQgKGxrLT5rZXljb2RlW2ldLCBsay0+ZGV2LmtleWJpdCk7CgoJbGstPmRldi5uYW1lID0gbGstPm5hbWU7Cglsay0+ZGV2LnBoeXMgPSBsay0+cGh5czsKCWxrLT5kZXYuaWQuYnVzdHlwZSA9IEJVU19SUzIzMjsKCWxrLT5kZXYuaWQudmVuZG9yID0gU0VSSU9fTEtLQkQ7Cglsay0+ZGV2LmlkLnByb2R1Y3QgPSAwOwoJbGstPmRldi5pZC52ZXJzaW9uID0gMHgwMTAwOwoJbGstPmRldi5kZXYgPSAmc2VyaW8tPmRldjsKCglpbnB1dF9yZWdpc3Rlcl9kZXZpY2UgKCZsay0+ZGV2KTsKCglwcmludGsgKEtFUk5fSU5GTyAiaW5wdXQ6ICVzIG9uICVzLCBpbml0aWF0aW5nIHJlc2V0XG4iLCBsay0+bmFtZSwgc2VyaW8tPnBoeXMpOwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfUE9XRVJDWUNMRV9SRVNFVCk7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIGxra2JkX2Rpc2Nvbm5lY3QoKSB1bnJlZ2lzdGVycyBhbmQgY2xvc2VzIGJlaGluZCB1cy4KICovCnN0YXRpYyB2b2lkCmxra2JkX2Rpc2Nvbm5lY3QgKHN0cnVjdCBzZXJpbyAqc2VyaW8pCnsKCXN0cnVjdCBsa2tiZCAqbGsgPSBzZXJpb19nZXRfZHJ2ZGF0YSAoc2VyaW8pOwoKCWlucHV0X3VucmVnaXN0ZXJfZGV2aWNlICgmbGstPmRldik7CglzZXJpb19jbG9zZSAoc2VyaW8pOwoJc2VyaW9fc2V0X2RydmRhdGEgKHNlcmlvLCBOVUxMKTsKCWtmcmVlIChsayk7Cn0KCnN0YXRpYyBzdHJ1Y3Qgc2VyaW9fZGV2aWNlX2lkIGxra2JkX3NlcmlvX2lkc1tdID0gewoJewoJCS50eXBlCT0gU0VSSU9fUlMyMzIsCgkJLnByb3RvCT0gU0VSSU9fTEtLQkQsCgkJLmlkCT0gU0VSSU9fQU5ZLAoJCS5leHRyYQk9IFNFUklPX0FOWSwKCX0sCgl7IDAgfQp9OwoKTU9EVUxFX0RFVklDRV9UQUJMRShzZXJpbywgbGtrYmRfc2VyaW9faWRzKTsKCnN0YXRpYyBzdHJ1Y3Qgc2VyaW9fZHJpdmVyIGxra2JkX2RydiA9IHsKCS5kcml2ZXIJCT0gewoJCS5uYW1lCT0gImxra2JkIiwKCX0sCgkuZGVzY3JpcHRpb24JPSBEUklWRVJfREVTQywKCS5pZF90YWJsZQk9IGxra2JkX3NlcmlvX2lkcywKCS5jb25uZWN0CT0gbGtrYmRfY29ubmVjdCwKCS5kaXNjb25uZWN0CT0gbGtrYmRfZGlzY29ubmVjdCwKCS5pbnRlcnJ1cHQJPSBsa2tiZF9pbnRlcnJ1cHQsCn07CgovKgogKiBUaGUgZnVuY3Rpb25zIGZvciBpbnNlcmluZy9yZW1vdmluZyB1cyBhcyBhIG1vZHVsZS4KICovCnN0YXRpYyBpbnQgX19pbml0Cmxra2JkX2luaXQgKHZvaWQpCnsKCXNlcmlvX3JlZ2lzdGVyX2RyaXZlcigmbGtrYmRfZHJ2KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQKbGtrYmRfZXhpdCAodm9pZCkKewoJc2VyaW9fdW5yZWdpc3Rlcl9kcml2ZXIoJmxra2JkX2Rydik7Cn0KCm1vZHVsZV9pbml0IChsa2tiZF9pbml0KTsKbW9kdWxlX2V4aXQgKGxra2JkX2V4aXQpOwoK