LyoKICogIENvcHlyaWdodCAoQykgMjAwNCBieSBKYW4tQmVuZWRpY3QgR2xhdyA8amJnbGF3QGx1Zy1vd2wuZGU+CiAqLwoKLyoKICogTEsga2V5Ym9hcmQgZHJpdmVyIGZvciBMaW51eCwgYmFzZWQgb24gc3Vua2JkLmMgKEMpIGJ5IFZvanRlY2ggUGF2bGlrCiAqLwoKLyoKICogREVDIExLMjAxIGFuZCBMSzQwMSBrZXlib2FyZCBkcml2ZXIgZm9yIExpbnV4IChwcmltYXJ5IGZvciBERUNzdGF0aW9ucwogKiBhbmQgVkFYc3RhdGlvbnMsIGJ1dCBjYW4gYWxzbyBiZSB1c2VkIG9uIGFueSBzdGFuZGFyZCBSUzIzMiB3aXRoIGFuCiAqIGFkYXB0b3IpLgogKgogKiBESVNDTEFJTUVSOiBUaGlzIHdvcmtzIGZvciBfbWVfLiBJZiB5b3UgYnJlYWsgYW55dGhpbmcgYnkgdXNpbmcgdGhlCiAqIGluZm9ybWF0aW9uIGdpdmVuIGJlbG93LCBJIHdpbGwgX25vdF8gYmUgbGlhYmxlIQogKgogKiBSSjEwIHBpbm91dDoJCVRvIERFOToJCU9yIERCMjU6CiAqCTEgLSBSeEQgPC0tLS0+CVBpbiAzIChUeEQpIDwtPglQaW4gMiAoVHhEKQogKgkyIC0gR05EIDwtLS0tPglQaW4gNSAoR05EKSA8LT4JUGluIDcgKEdORCkKICoJNCAtIFR4RCA8LS0tLT4JUGluIDIgKFJ4RCkgPC0+CVBpbiAzIChSeEQpCiAqCTMgLSArMTJWIChmcm9tIEhERCBkcml2ZSBjb25uZWN0b3IpLCBET04nVCBjb25uZWN0IHRvIERFOSBvciBEQjI1ISEhCiAqCiAqIFBpbiBudW1iZXJzIGZvciBERTkgYW5kIERCMjUgYXJlIG5vdGVkIG9uIHRoZSBwbHVnIChxdWl0ZSBzbWFsbDopLiBGb3IKICogUkoxMCwgaXQncyBsaWtlIHRoaXM6CiAqCiAqICAgICAgX189X18JSG9sZCB0aGUgcGx1ZyBpbiBmcm9udCBvZiB5b3UsIGNhYmxlIGRvd253YXJkcywKICogICAgIC9fX18vfAlub3NlIGlzIGhpZGRlbiBiZWhpbmQgdGhlIHBsdWcuIE5vdywgcGluIDEgaXMgYXQKICogICAgfDEyMzR8fAl0aGUgbGVmdCBzaWRlLCBwaW4gNCBhdCB0aGUgcmlnaHQgYW5kIDIgYW5kIDMgYXJlCiAqICAgIHxJSUlJfHwJaW4gYmV0d2Vlbiwgb2YgY291cnNlOikKICogICAgfCAgICB8fAogKiAgICB8X19fX3wvCiAqICAgICAgfHwJU28gdGhlIGFkYXB0b3IgY29uc2lzdHMgb2YgdGhyZWUgY29ubmVjdGVkIGNhYmxlcwogKiAgICAgIHx8CWZvciBkYXRhIHRyYW5zbWlzc2lvbiAoUnhEIGFuZCBUeEQpIGFuZCBzaWduYWwgZ3JvdW5kLgogKgkJQWRkaXRpb25hbGx5LCB5b3UgaGF2ZSB0byBnZXQgKzEyViBmcm9tIHNvbWV3aGVyZS4KICogTW9zdCBlYXNpbHksIHlvdSdsbCBnZXQgdGhhdCBmcm9tIGEgZmxvcHB5IG9yIEhERCBwb3dlciBjb25uZWN0b3IuCiAqIEl0J3MgdGhlIHllbGxvdyBjYWJsZSB0aGVyZSAoYmxhY2sgaXMgZ3JvdW5kIGFuZCByZWQgaXMgKzVWKS4KICoKICogVGhlIGtleWJvYXJkIGFuZCBhbGwgdGhlIGNvbW1hbmRzIGl0IHVuZGVyc3RhbmRzIGFyZSBkb2N1bWVudGVkIGluCiAqICJWQ0IwMiBWaWRlbyBTdWJzeXN0ZW0gLSBUZWNobmljYWwgTWFudWFsIiwgRUstMTA0QUEtVE0tMDAxLiBUaGlzCiAqIGRvY3VtZW50IGlzIExLMjAxIHNwZWNpZmljLCBidXQgTEs0MDEgaXMgbW9zdGx5IGNvbXBhdGlibGUuIEl0IGNvbWVzCiAqIHVwIGluIExLMjAxIG1vZGUgYW5kIGRvZXNuJ3QgcmVwb3J0IGFueSBvZiB0aGUgYWRkaXRpb25hbCBrZXlzIGl0CiAqIGhhcy4gVGhlc2UgbmVlZCB0byBiZSBzd2l0Y2hlZCBvbiB3aXRoIHRoZSBMS19DTURfRU5BQkxFX0xLNDAxCiAqIGNvbW1hbmQuIFlvdSdsbCBmaW5kIHRoaXMgZG9jdW1lbnQgKHNjYW5uZWQgLnBkZiBmaWxlKSBvbiBNQU5YLAogKiBhIHNlYXJjaCBlbmdpbmUgc3BlY2lmaWMgdG8gREVDIGRvY3VtZW50YXRpb24uIFRyeQogKiBodHRwOi8vd3d3LnZ0MTAwLm5ldC9tYW54L2RldGFpbHM/cG49RUstMTA0QUEtVE0tMDAxO2lkPTIxO2NwPTEKICovCgovKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3IFVTQQogKgogKiBTaG91bGQgeW91IG5lZWQgdG8gY29udGFjdCBtZSwgdGhlIGF1dGhvciwgeW91IGNhbiBkbyBzbyBlaXRoZXIgYnkKICogZW1haWwgb3IgYnkgcGFwZXIgbWFpbDoKICogSmFuLUJlbmVkaWN0IEdsYXcsIExpbGllbnN0cmHfZSAxNiwgMzM3OTAgSPZyc3RlIChuZWFyIEhhbGxlL1dlc3RmLiksCiAqIEdlcm1hbnkuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZXBhcmFtLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2lucHV0Lmg+CiNpbmNsdWRlIDxsaW51eC9zZXJpby5oPgojaW5jbHVkZSA8bGludXgvd29ya3F1ZXVlLmg+CgojZGVmaW5lIERSSVZFUl9ERVNDCSJMSyBrZXlib2FyZCBkcml2ZXIiCgpNT0RVTEVfQVVUSE9SICgiSmFuLUJlbmVkaWN0IEdsYXcgPGpiZ2xhd0BsdWctb3dsLmRlPiIpOwpNT0RVTEVfREVTQ1JJUFRJT04gKERSSVZFUl9ERVNDKTsKTU9EVUxFX0xJQ0VOU0UgKCJHUEwiKTsKCi8qCiAqIEtub3duIHBhcmFtZXRlcnM6CiAqCWJlbGxfdm9sdW1lCiAqCWtleWNsaWNrX3ZvbHVtZQogKgljdHJsY2xpY2tfdm9sdW1lCiAqCiAqIFBsZWFzZSBub3RpY2UgdGhhdCB0aGVyZSdzIG5vdCB5ZXQgYW4gQVBJIHRvIHNldCB0aGVzZSBhdCBydW50aW1lLgogKi8Kc3RhdGljIGludCBiZWxsX3ZvbHVtZSA9IDEwMDsgLyogJSAqLwptb2R1bGVfcGFyYW0gKGJlbGxfdm9sdW1lLCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDIChiZWxsX3ZvbHVtZSwgIkJlbGwgdm9sdW1lIChpbiAlKS4gZGVmYXVsdCBpcyAxMDAlIik7CgpzdGF0aWMgaW50IGtleWNsaWNrX3ZvbHVtZSA9IDEwMDsgLyogJSAqLwptb2R1bGVfcGFyYW0gKGtleWNsaWNrX3ZvbHVtZSwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyAoa2V5Y2xpY2tfdm9sdW1lLCAiS2V5Y2xpY2sgdm9sdW1lIChpbiAlKSwgZGVmYXVsdCBpcyAxMDAlIik7CgpzdGF0aWMgaW50IGN0cmxjbGlja192b2x1bWUgPSAxMDA7IC8qICUgKi8KbW9kdWxlX3BhcmFtIChjdHJsY2xpY2tfdm9sdW1lLCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDIChjdHJsY2xpY2tfdm9sdW1lLCAiQ3RybGNsaWNrIHZvbHVtZSAoaW4gJSksIGRlZmF1bHQgaXMgMTAwJSIpOwoKc3RhdGljIGludCBsazIwMV9jb21wb3NlX2lzX2FsdDsKbW9kdWxlX3BhcmFtIChsazIwMV9jb21wb3NlX2lzX2FsdCwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyAobGsyMDFfY29tcG9zZV9pc19hbHQsICJJZiBzZXQgbm9uLXplcm8sIExLMjAxJyBDb21wb3NlIGtleSAiCgkJIndpbGwgYWN0IGFzIGFuIEFsdCBrZXkiKTsKCgoKI3VuZGVmIExLS0JEX0RFQlVHCiNpZmRlZiBMS0tCRF9ERUJVRwojZGVmaW5lIERCRyh4Li4uKSBwcmludGsgKHgpCiNlbHNlCiNkZWZpbmUgREJHKHguLi4pIGRvIHt9IHdoaWxlICgwKQojZW5kaWYKCi8qIExFRCBjb250cm9sICovCiNkZWZpbmUgTEtfTEVEX1dBSVQJCTB4ODEKI2RlZmluZSBMS19MRURfQ09NUE9TRQkJMHg4MgojZGVmaW5lIExLX0xFRF9TSElGVExPQ0sJMHg4NAojZGVmaW5lIExLX0xFRF9TQ1JPTExMT0NLCTB4ODgKI2RlZmluZSBMS19DTURfTEVEX09OCQkweDEzCiNkZWZpbmUgTEtfQ01EX0xFRF9PRkYJCTB4MTEKCi8qIE1vZGUgY29udHJvbCAqLwojZGVmaW5lIExLX01PREVfRE9XTgkJMHg4MAojZGVmaW5lIExLX01PREVfQVVUT0RPV04JMHg4MgojZGVmaW5lIExLX01PREVfVVBET1dOCQkweDg2CiNkZWZpbmUgTEtfQ01EX1NFVF9NT0RFKG1vZGUsZGl2KQkoKG1vZGUpIHwgKChkaXYpIDw8IDMpKQoKLyogTWlzYyBjb21tYW5kcyAqLwojZGVmaW5lIExLX0NNRF9FTkFCTEVfS0VZQ0xJQ0sJMHgxYgojZGVmaW5lIExLX0NNRF9ESVNBQkxFX0tFWUNMSUNLCTB4OTkKI2RlZmluZSBMS19DTURfRElTQUJMRV9CRUxMCTB4YTEKI2RlZmluZSBMS19DTURfU09VTkRfQkVMTAkweGE3CiNkZWZpbmUgTEtfQ01EX0VOQUJMRV9CRUxMCTB4MjMKI2RlZmluZSBMS19DTURfRElTQUJMRV9DVFJDTElDSwkweGI5CiNkZWZpbmUgTEtfQ01EX0VOQUJMRV9DVFJDTElDSwkweGJiCiNkZWZpbmUgTEtfQ01EX1NFVF9ERUZBVUxUUwkweGQzCiNkZWZpbmUgTEtfQ01EX1BPV0VSQ1lDTEVfUkVTRVQJMHhmZAojZGVmaW5lIExLX0NNRF9FTkFCTEVfTEs0MDEJMHhlOQojZGVmaW5lIExLX0NNRF9SRVFVRVNUX0lECTB4YWIKCi8qIE1pc2MgcmVzcG9uc2VzIGZyb20ga2V5Ym9hcmQgKi8KI2RlZmluZSBMS19TVFVDS19LRVkJCTB4M2QKI2RlZmluZSBMS19TRUxGVEVTVF9GQUlMRUQJMHgzZQojZGVmaW5lIExLX0FMTF9LRVlTX1VQCQkweGIzCiNkZWZpbmUgTEtfTUVUUk9OT01FCQkweGI0CiNkZWZpbmUgTEtfT1VUUFVUX0VSUk9SCQkweGI1CiNkZWZpbmUgTEtfSU5QVVRfRVJST1IJCTB4YjYKI2RlZmluZSBMS19LQkRfTE9DS0VECQkweGI3CiNkZWZpbmUgTEtfS0JEX1RFU1RfTU9ERV9BQ0sJMHhiOAojZGVmaW5lIExLX1BSRUZJWF9LRVlfRE9XTgkweGI5CiNkZWZpbmUgTEtfTU9ERV9DSEFOR0VfQUNLCTB4YmEKI2RlZmluZSBMS19SRVNQT05TRV9SRVNFUlZFRAkweGJiCgojZGVmaW5lIExLX05VTV9LRVlDT0RFUwkJMjU2CiNkZWZpbmUgTEtfTlVNX0lHTk9SRV9CWVRFUwk2CnR5cGVkZWYgdV9pbnQxNl90IGxrX2tleWNvZGVfdDsKCgoKc3RhdGljIGxrX2tleWNvZGVfdCBsa2tiZF9rZXljb2RlW0xLX05VTV9LRVlDT0RFU10gPSB7CglbMHg1Nl0gPSBLRVlfRjEsCglbMHg1N10gPSBLRVlfRjIsCglbMHg1OF0gPSBLRVlfRjMsCglbMHg1OV0gPSBLRVlfRjQsCglbMHg1YV0gPSBLRVlfRjUsCglbMHg2NF0gPSBLRVlfRjYsCglbMHg2NV0gPSBLRVlfRjcsCglbMHg2Nl0gPSBLRVlfRjgsCglbMHg2N10gPSBLRVlfRjksCglbMHg2OF0gPSBLRVlfRjEwLAoJWzB4NzFdID0gS0VZX0YxMSwKCVsweDcyXSA9IEtFWV9GMTIsCglbMHg3M10gPSBLRVlfRjEzLAoJWzB4NzRdID0gS0VZX0YxNCwKCVsweDdjXSA9IEtFWV9GMTUsCglbMHg3ZF0gPSBLRVlfRjE2LAoJWzB4ODBdID0gS0VZX0YxNywKCVsweDgxXSA9IEtFWV9GMTgsCglbMHg4Ml0gPSBLRVlfRjE5LAoJWzB4ODNdID0gS0VZX0YyMCwKCVsweDhhXSA9IEtFWV9GSU5ELAoJWzB4OGJdID0gS0VZX0lOU0VSVCwKCVsweDhjXSA9IEtFWV9ERUxFVEUsCglbMHg4ZF0gPSBLRVlfU0VMRUNULAoJWzB4OGVdID0gS0VZX1BBR0VVUCwKCVsweDhmXSA9IEtFWV9QQUdFRE9XTiwKCVsweDkyXSA9IEtFWV9LUDAsCglbMHg5NF0gPSBLRVlfS1BET1QsCglbMHg5NV0gPSBLRVlfS1BFTlRFUiwKCVsweDk2XSA9IEtFWV9LUDEsCglbMHg5N10gPSBLRVlfS1AyLAoJWzB4OThdID0gS0VZX0tQMywKCVsweDk5XSA9IEtFWV9LUDQsCglbMHg5YV0gPSBLRVlfS1A1LAoJWzB4OWJdID0gS0VZX0tQNiwKCVsweDljXSA9IEtFWV9LUENPTU1BLAoJWzB4OWRdID0gS0VZX0tQNywKCVsweDllXSA9IEtFWV9LUDgsCglbMHg5Zl0gPSBLRVlfS1A5LAoJWzB4YTBdID0gS0VZX0tQTUlOVVMsCglbMHhhMV0gPSBLRVlfUFJPRzEsCglbMHhhMl0gPSBLRVlfUFJPRzIsCglbMHhhM10gPSBLRVlfUFJPRzMsCglbMHhhNF0gPSBLRVlfUFJPRzQsCglbMHhhN10gPSBLRVlfTEVGVCwKCVsweGE4XSA9IEtFWV9SSUdIVCwKCVsweGE5XSA9IEtFWV9ET1dOLAoJWzB4YWFdID0gS0VZX1VQLAoJWzB4YWJdID0gS0VZX1JJR0hUU0hJRlQsCglbMHhhY10gPSBLRVlfTEVGVEFMVCwKCVsweGFkXSA9IEtFWV9DT01QT1NFLCAvKiBSaWdodCBDb21wb3NlLCB0aGF0IGlzLiAqLwoJWzB4YWVdID0gS0VZX0xFRlRTSElGVCwgLyogU2FtZSBhcyBLRVlfUklHSFRTSElGVCBvbiBMSzIwMSAqLwoJWzB4YWZdID0gS0VZX0xFRlRDVFJMLAoJWzB4YjBdID0gS0VZX0NBUFNMT0NLLAoJWzB4YjFdID0gS0VZX0NPTVBPU0UsIC8qIExlZnQgQ29tcG9zZSwgdGhhdCBpcy4gKi8KCVsweGIyXSA9IEtFWV9SSUdIVEFMVCwKCVsweGJjXSA9IEtFWV9CQUNLU1BBQ0UsCglbMHhiZF0gPSBLRVlfRU5URVIsCglbMHhiZV0gPSBLRVlfVEFCLAoJWzB4YmZdID0gS0VZX0VTQywKCVsweGMwXSA9IEtFWV8xLAoJWzB4YzFdID0gS0VZX1EsCglbMHhjMl0gPSBLRVlfQSwKCVsweGMzXSA9IEtFWV9aLAoJWzB4YzVdID0gS0VZXzIsCglbMHhjNl0gPSBLRVlfVywKCVsweGM3XSA9IEtFWV9TLAoJWzB4YzhdID0gS0VZX1gsCglbMHhjOV0gPSBLRVlfMTAyTkQsCglbMHhjYl0gPSBLRVlfMywKCVsweGNjXSA9IEtFWV9FLAoJWzB4Y2RdID0gS0VZX0QsCglbMHhjZV0gPSBLRVlfQywKCVsweGQwXSA9IEtFWV80LAoJWzB4ZDFdID0gS0VZX1IsCglbMHhkMl0gPSBLRVlfRiwKCVsweGQzXSA9IEtFWV9WLAoJWzB4ZDRdID0gS0VZX1NQQUNFLAoJWzB4ZDZdID0gS0VZXzUsCglbMHhkN10gPSBLRVlfVCwKCVsweGQ4XSA9IEtFWV9HLAoJWzB4ZDldID0gS0VZX0IsCglbMHhkYl0gPSBLRVlfNiwKCVsweGRjXSA9IEtFWV9ZLAoJWzB4ZGRdID0gS0VZX0gsCglbMHhkZV0gPSBLRVlfTiwKCVsweGUwXSA9IEtFWV83LAoJWzB4ZTFdID0gS0VZX1UsCglbMHhlMl0gPSBLRVlfSiwKCVsweGUzXSA9IEtFWV9NLAoJWzB4ZTVdID0gS0VZXzgsCglbMHhlNl0gPSBLRVlfSSwKCVsweGU3XSA9IEtFWV9LLAoJWzB4ZThdID0gS0VZX0NPTU1BLAoJWzB4ZWFdID0gS0VZXzksCglbMHhlYl0gPSBLRVlfTywKCVsweGVjXSA9IEtFWV9MLAoJWzB4ZWRdID0gS0VZX0RPVCwKCVsweGVmXSA9IEtFWV8wLAoJWzB4ZjBdID0gS0VZX1AsCglbMHhmMl0gPSBLRVlfU0VNSUNPTE9OLAoJWzB4ZjNdID0gS0VZX1NMQVNILAoJWzB4ZjVdID0gS0VZX0VRVUFMLAoJWzB4ZjZdID0gS0VZX1JJR0hUQlJBQ0UsCglbMHhmN10gPSBLRVlfQkFDS1NMQVNILAoJWzB4ZjldID0gS0VZX01JTlVTLAoJWzB4ZmFdID0gS0VZX0xFRlRCUkFDRSwKCVsweGZiXSA9IEtFWV9BUE9TVFJPUEhFLAp9OwoKI2RlZmluZSBDSEVDS19MRUQoTEVELCBCSVRTKSBkbyB7CQlcCglpZiAodGVzdF9iaXQgKExFRCwgbGstPmRldi0+bGVkKSkJXAoJCWxlZHNfb24gfD0gQklUUzsJCVwKCWVsc2UJCQkJCVwKCQlsZWRzX29mZiB8PSBCSVRTOwkJXAoJfSB3aGlsZSAoMCkKCi8qCiAqIFBlci1rZXlib2FyZCBkYXRhCiAqLwpzdHJ1Y3QgbGtrYmQgewoJbGtfa2V5Y29kZV90IGtleWNvZGVbTEtfTlVNX0tFWUNPREVTXTsKCWludCBpZ25vcmVfYnl0ZXM7Cgl1bnNpZ25lZCBjaGFyIGlkW0xLX05VTV9JR05PUkVfQllURVNdOwoJc3RydWN0IGlucHV0X2RldiAqZGV2OwoJc3RydWN0IHNlcmlvICpzZXJpbzsKCXN0cnVjdCB3b3JrX3N0cnVjdCB0cTsKCWNoYXIgbmFtZVs2NF07CgljaGFyIHBoeXNbMzJdOwoJY2hhciB0eXBlOwoJaW50IGJlbGxfdm9sdW1lOwoJaW50IGtleWNsaWNrX3ZvbHVtZTsKCWludCBjdHJsY2xpY2tfdm9sdW1lOwp9OwoKLyoKICogQ2FsY3VsYXRlIHZvbHVtZSBwYXJhbWV0ZXIgYnl0ZSBmb3IgYSBnaXZlbiB2b2x1bWUuCiAqLwpzdGF0aWMgdW5zaWduZWQgY2hhcgp2b2x1bWVfdG9faHcgKGludCB2b2x1bWVfcGVyY2VudCkKewoJdW5zaWduZWQgY2hhciByZXQgPSAwOwoKCWlmICh2b2x1bWVfcGVyY2VudCA8IDApCgkJdm9sdW1lX3BlcmNlbnQgPSAwOwoJaWYgKHZvbHVtZV9wZXJjZW50ID4gMTAwKQoJCXZvbHVtZV9wZXJjZW50ID0gMTAwOwoKCWlmICh2b2x1bWVfcGVyY2VudCA+PSAwKQoJCXJldCA9IDc7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gMTMpCS8qIDEyLjUgKi8KCQlyZXQgPSA2OwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDI1KQoJCXJldCA9IDU7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gMzgpCS8qIDM3LjUgKi8KCQlyZXQgPSA0OwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDUwKQoJCXJldCA9IDM7CglpZiAodm9sdW1lX3BlcmNlbnQgPj0gNjMpCS8qIDYyLjUgKi8KCQlyZXQgPSAyOwkJLyogVGhpcyBpcyB0aGUgZGVmYXVsdCB2b2x1bWUgKi8KCWlmICh2b2x1bWVfcGVyY2VudCA+PSA3NSkKCQlyZXQgPSAxOwoJaWYgKHZvbHVtZV9wZXJjZW50ID49IDg4KQkvKiA4Ny41ICovCgkJcmV0ID0gMDsKCglyZXQgfD0gMHg4MDsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZApsa2tiZF9kZXRlY3Rpb25fZG9uZSAoc3RydWN0IGxra2JkICpsaykKewoJaW50IGk7CgoJLyoKCSAqIFJlc2V0IHNldHRpbmcgZm9yIENvbXBvc2Uga2V5LiBMZXQgQ29tcG9zZSBiZSBLRVlfQ09NUE9TRS4KCSAqLwoJbGstPmtleWNvZGVbMHhiMV0gPSBLRVlfQ09NUE9TRTsKCgkvKgoJICogUHJpbnQga2V5Ym9hcmQgbmFtZSBhbmQgbW9kaWZ5IENvbXBvc2U9QWx0IG9uIHVzZXIncyByZXF1ZXN0LgoJICovCglzd2l0Y2ggKGxrLT5pZFs0XSkgewoJCWNhc2UgMToKCQkJc3ByaW50ZiAobGstPm5hbWUsICJERUMgTEsyMDEga2V5Ym9hcmQiKTsKCgkJCWlmIChsazIwMV9jb21wb3NlX2lzX2FsdCkKCQkJCWxrLT5rZXljb2RlWzB4YjFdID0gS0VZX0xFRlRBTFQ7CgkJCWJyZWFrOwoKCQljYXNlIDI6CgkJCXNwcmludGYgKGxrLT5uYW1lLCAiREVDIExLNDAxIGtleWJvYXJkIik7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlzcHJpbnRmIChsay0+bmFtZSwgIlVua25vd24gREVDIGtleWJvYXJkIik7CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBrZXlib2FyZCBvbiAlcyBpcyB1bmtub3duLCAiCgkJCQkJInBsZWFzZSByZXBvcnQgdG8gSmFuLUJlbmVkaWN0IEdsYXcgIgoJCQkJCSI8amJnbGF3QGx1Zy1vd2wuZGU+XG4iLCBsay0+cGh5cyk7CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBrZXlib2FyZCBJRCdlZCBhczoiKTsKCQkJZm9yIChpID0gMDsgaSA8IExLX05VTV9JR05PUkVfQllURVM7IGkrKykKCQkJCXByaW50ayAoIiAweCUwMngiLCBsay0+aWRbaV0pOwoJCQlwcmludGsgKCJcbiIpOwoJCQlicmVhazsKCX0KCXByaW50ayAoS0VSTl9JTkZPICJsa2tiZDoga2V5Ym9hcmQgb24gJXMgaWRlbnRpZmllZCBhczogJXNcbiIsCgkJCWxrLT5waHlzLCBsay0+bmFtZSk7CgoJLyoKCSAqIFJlcG9ydCBlcnJvcnMgZHVyaW5nIGtleWJvYXJkIGJvb3QtdXAuCgkgKi8KCXN3aXRjaCAobGstPmlkWzJdKSB7CgkJY2FzZSAweDAwOgoJCQkvKiBBbGwgb2theSAqLwoJCQlicmVhazsKCgkJY2FzZSBMS19TVFVDS19LRVk6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBTdHVjayBrZXkgb24ga2V5Ym9hcmQgYXQgIgoJCQkJCSIlc1xuIiwgbGstPnBoeXMpOwoJCQlicmVhazsKCgkJY2FzZSBMS19TRUxGVEVTVF9GQUlMRUQ6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBTZWxmdGVzdCBmYWlsZWQgb24ga2V5Ym9hcmQgIgoJCQkJCSJhdCAlcywga2V5Ym9hcmQgbWF5IG5vdCB3b3JrICIKCQkJCQkicHJvcGVybHlcbiIsIGxrLT5waHlzKTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCXByaW50ayAoS0VSTl9FUlIgImxra2JkOiBVbmtub3duIGVycm9yICUwMnggb24gIgoJCQkJCSJrZXlib2FyZCBhdCAlc1xuIiwgbGstPmlkWzJdLAoJCQkJCWxrLT5waHlzKTsKCQkJYnJlYWs7Cgl9CgoJLyoKCSAqIFRyeSB0byBoaW50IHVzZXIgaWYgdGhlcmUncyBhIHN0dWNrIGtleS4KCSAqLwoJaWYgKGxrLT5pZFsyXSA9PSBMS19TVFVDS19LRVkgJiYgbGstPmlkWzNdICE9IDApCgkJcHJpbnRrIChLRVJOX0VSUiAiU2NhbmNvZGUgb2Ygc3R1Y2sga2V5IGlzIDB4JTAyeCwga2V5Y29kZSAiCgkJCQkiaXMgMHglMDR4XG4iLCBsay0+aWRbM10sCgkJCQlsay0+a2V5Y29kZVtsay0+aWRbM11dKTsKCglyZXR1cm47Cn0KCi8qCiAqIGxra2JkX2ludGVycnVwdCgpIGlzIGNhbGxlZCBieSB0aGUgbG93IGxldmVsIGRyaXZlciB3aGVuIGEgY2hhcmFjdGVyCiAqIGlzIHJlY2VpdmVkLgogKi8Kc3RhdGljIGlycXJldHVybl90Cmxra2JkX2ludGVycnVwdCAoc3RydWN0IHNlcmlvICpzZXJpbywgdW5zaWduZWQgY2hhciBkYXRhLCB1bnNpZ25lZCBpbnQgZmxhZ3MsCgkJc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBsa2tiZCAqbGsgPSBzZXJpb19nZXRfZHJ2ZGF0YSAoc2VyaW8pOwoJaW50IGk7CgoJREJHIChLRVJOX0lORk8gIkdvdCBieXRlIDB4JTAyeFxuIiwgZGF0YSk7CgoJaWYgKGxrLT5pZ25vcmVfYnl0ZXMgPiAwKSB7CgkJREJHIChLRVJOX0lORk8gIklnbm9yaW5nIGEgYnl0ZSBvbiAlc1xuIiwgbGstPm5hbWUpOwoJCWxrLT5pZFtMS19OVU1fSUdOT1JFX0JZVEVTIC0gbGstPmlnbm9yZV9ieXRlcy0tXSA9IGRhdGE7CgoJCWlmIChsay0+aWdub3JlX2J5dGVzID09IDApCgkJCWxra2JkX2RldGVjdGlvbl9kb25lIChsayk7CgoJCXJldHVybiBJUlFfSEFORExFRDsKCX0KCglzd2l0Y2ggKGRhdGEpIHsKCQljYXNlIExLX0FMTF9LRVlTX1VQOgoJCQlpbnB1dF9yZWdzIChsay0+ZGV2LCByZWdzKTsKCQkJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUgKGxra2JkX2tleWNvZGUpOyBpKyspCgkJCQlpZiAobGstPmtleWNvZGVbaV0gIT0gS0VZX1JFU0VSVkVEKQoJCQkJCWlucHV0X3JlcG9ydF9rZXkgKGxrLT5kZXYsIGxrLT5rZXljb2RlW2ldLCAwKTsKCQkJaW5wdXRfc3luYyAobGstPmRldik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfTUVUUk9OT01FOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX01FVFJPTk9NRSBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX09VVFBVVF9FUlJPUjoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19PVVRQVVRfRVJST1IgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSBMS19JTlBVVF9FUlJPUjoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19JTlBVVF9FUlJPUiBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX0tCRF9MT0NLRUQ6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfS0JEX0xPQ0tFRCBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX0tCRF9URVNUX01PREVfQUNLOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX0tCRF9URVNUX01PREVfQUNLIGFuZCBkb24ndCAiCgkJCQkJImtub3cgaG93IHRvIGhhbmRsZS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfUFJFRklYX0tFWV9ET1dOOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IExLX1BSRUZJWF9LRVlfRE9XTiBhbmQgZG9uJ3QgIgoJCQkJCSJrbm93IGhvdyB0byBoYW5kbGUuLi5cbiIpOwoJCQlicmVhazsKCQljYXNlIExLX01PREVfQ0hBTkdFX0FDSzoKCQkJREJHIChLRVJOX0lORk8gIkdvdCBMS19NT0RFX0NIQU5HRV9BQ0sgYW5kIGlnbm9yZWQgIgoJCQkJCSJpdCBwcm9wZXJseS4uLlxuIik7CgkJCWJyZWFrOwoJCWNhc2UgTEtfUkVTUE9OU0VfUkVTRVJWRUQ6CgkJCURCRyAoS0VSTl9JTkZPICJHb3QgTEtfUkVTUE9OU0VfUkVTRVJWRUQgYW5kIGRvbid0ICIKCQkJCQkia25vdyBob3cgdG8gaGFuZGxlLi4uXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSAweDAxOgoJCQlEQkcgKEtFUk5fSU5GTyAiR290IDB4MDEsIHNjaGVkdWxpbmcgcmUtaW5pdGlhbGl6YXRpb25cbiIpOwoJCQlsay0+aWdub3JlX2J5dGVzID0gTEtfTlVNX0lHTk9SRV9CWVRFUzsKCQkJbGstPmlkW0xLX05VTV9JR05PUkVfQllURVMgLSBsay0+aWdub3JlX2J5dGVzLS1dID0gZGF0YTsKCQkJc2NoZWR1bGVfd29yayAoJmxrLT50cSk7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlpZiAobGstPmtleWNvZGVbZGF0YV0gIT0gS0VZX1JFU0VSVkVEKSB7CgkJCQlpbnB1dF9yZWdzIChsay0+ZGV2LCByZWdzKTsKCQkJCWlmICghdGVzdF9iaXQgKGxrLT5rZXljb2RlW2RhdGFdLCBsay0+ZGV2LT5rZXkpKQoJCQkJCWlucHV0X3JlcG9ydF9rZXkgKGxrLT5kZXYsIGxrLT5rZXljb2RlW2RhdGFdLCAxKTsKCQkJCWVsc2UKCQkJCQlpbnB1dF9yZXBvcnRfa2V5IChsay0+ZGV2LCBsay0+a2V5Y29kZVtkYXRhXSwgMCk7CgkJCQlpbnB1dF9zeW5jIChsay0+ZGV2KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRrIChLRVJOX1dBUk5JTkcgIiVzOiBVbmtub3duIGtleSB3aXRoICIKCQkJCQkJInNjYW5jb2RlIDB4JTAyeCBvbiAlcy5cbiIsCgkJCQkJCV9fRklMRV9fLCBkYXRhLCBsay0+bmFtZSk7Cgl9CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgovKgogKiBsa2tiZF9ldmVudCgpIGhhbmRsZXMgZXZlbnRzIGZyb20gdGhlIGlucHV0IG1vZHVsZS4KICovCnN0YXRpYyBpbnQKbGtrYmRfZXZlbnQgKHN0cnVjdCBpbnB1dF9kZXYgKmRldiwgdW5zaWduZWQgaW50IHR5cGUsIHVuc2lnbmVkIGludCBjb2RlLAoJCWludCB2YWx1ZSkKewoJc3RydWN0IGxra2JkICpsayA9IGRldi0+cHJpdmF0ZTsKCXVuc2lnbmVkIGNoYXIgbGVkc19vbiA9IDA7Cgl1bnNpZ25lZCBjaGFyIGxlZHNfb2ZmID0gMDsKCglzd2l0Y2ggKHR5cGUpIHsKCQljYXNlIEVWX0xFRDoKCQkJQ0hFQ0tfTEVEIChMRURfQ0FQU0wsIExLX0xFRF9TSElGVExPQ0spOwoJCQlDSEVDS19MRUQgKExFRF9DT01QT1NFLCBMS19MRURfQ09NUE9TRSk7CgkJCUNIRUNLX0xFRCAoTEVEX1NDUk9MTEwsIExLX0xFRF9TQ1JPTExMT0NLKTsKCQkJQ0hFQ0tfTEVEIChMRURfU0xFRVAsIExLX0xFRF9XQUlUKTsKCQkJaWYgKGxlZHNfb24gIT0gMCkgewoJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfTEVEX09OKTsKCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgbGVkc19vbik7CgkJCX0KCQkJaWYgKGxlZHNfb2ZmICE9IDApIHsKCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0xFRF9PRkYpOwoJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBsZWRzX29mZik7CgkJCX0KCQkJcmV0dXJuIDA7CgoJCWNhc2UgRVZfU05EOgoJCQlzd2l0Y2ggKGNvZGUpIHsKCQkJCWNhc2UgU05EX0NMSUNLOgoJCQkJCWlmICh2YWx1ZSA9PSAwKSB7CgkJCQkJCURCRyAoIiVzOiBEZWFjdGl2YXRpbmcga2V5IGNsaWNrc1xuIiwgX19GVU5DVElPTl9fKTsKCQkJCQkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfRElTQUJMRV9LRVlDTElDSyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0RJU0FCTEVfQ1RSQ0xJQ0spOwoJCQkJCX0gZWxzZSB7CgkJCQkJCURCRyAoIiVzOiBBY3RpdmF0aW5nIGtleSBjbGlja3NcbiIsIF9fRlVOQ1RJT05fXyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9LRVlDTElDSyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+a2V5Y2xpY2tfdm9sdW1lKSk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9DVFJDTElDSyk7CgkJCQkJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+Y3RybGNsaWNrX3ZvbHVtZSkpOwoJCQkJCX0KCQkJCQlyZXR1cm4gMDsKCgkJCQljYXNlIFNORF9CRUxMOgoJCQkJCWlmICh2YWx1ZSAhPSAwKQoJCQkJCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9TT1VORF9CRUxMKTsKCgkJCQkJcmV0dXJuIDA7CgkJCX0KCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCXByaW50ayAoS0VSTl9FUlIgIiVzICgpOiBHb3QgdW5rbm93biB0eXBlICVkLCBjb2RlICVkLCB2YWx1ZSAlZFxuIiwKCQkJCQlfX0ZVTkNUSU9OX18sIHR5cGUsIGNvZGUsIHZhbHVlKTsKCX0KCglyZXR1cm4gLTE7Cn0KCi8qCiAqIGxra2JkX3JlaW5pdCgpIHNldHMgbGVkcyBhbmQgYmVlcHMgdG8gYSBzdGF0ZSB0aGUgY29tcHV0ZXIgcmVtZW1iZXJzIHRoZXkKICogd2VyZSBpbi4KICovCnN0YXRpYyB2b2lkCmxra2JkX3JlaW5pdCAodm9pZCAqZGF0YSkKewoJc3RydWN0IGxra2JkICpsayA9IGRhdGE7CglpbnQgZGl2aXNpb247Cgl1bnNpZ25lZCBjaGFyIGxlZHNfb24gPSAwOwoJdW5zaWduZWQgY2hhciBsZWRzX29mZiA9IDA7CgoJLyogQXNrIGZvciBJRCAqLwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfUkVRVUVTVF9JRCk7CgoJLyogUmVzZXQgcGFyYW1ldGVycyAqLwoJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfU0VUX0RFRkFVTFRTKTsKCgkvKiBTZXQgTEVEcyAqLwoJQ0hFQ0tfTEVEIChMRURfQ0FQU0wsIExLX0xFRF9TSElGVExPQ0spOwoJQ0hFQ0tfTEVEIChMRURfQ09NUE9TRSwgTEtfTEVEX0NPTVBPU0UpOwoJQ0hFQ0tfTEVEIChMRURfU0NST0xMTCwgTEtfTEVEX1NDUk9MTExPQ0spOwoJQ0hFQ0tfTEVEIChMRURfU0xFRVAsIExLX0xFRF9XQUlUKTsKCWlmIChsZWRzX29uICE9IDApIHsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9MRURfT04pOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgbGVkc19vbik7Cgl9CglpZiAobGVkc19vZmYgIT0gMCkgewoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0xFRF9PRkYpOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgbGVkc19vZmYpOwoJfQoKCS8qCgkgKiBUcnkgdG8gYWN0aXZhdGUgZXh0ZW5kZWQgTEs0MDEgbW9kZS4gVGhpcyBjb21tYW5kIHdpbGwKCSAqIG9ubHkgd29yayB3aXRoIGEgTEs0MDEga2V5Ym9hcmQgYW5kIGdyYW50cyBhY2Nlc3MgdG8KCSAqIExBbHQsIFJBbHQsIFJDb21wb3NlIGFuZCBSU2hpZnQuCgkgKi8KCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9MSzQwMSk7CgoJLyogU2V0IGFsbCBrZXlzIHRvIFVQRE9XTiBtb2RlICovCglmb3IgKGRpdmlzaW9uID0gMTsgZGl2aXNpb24gPD0gMTQ7IGRpdmlzaW9uKyspCgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfU0VUX01PREUgKExLX01PREVfVVBET1dOLAoJCQkJCWRpdmlzaW9uKSk7CgoJLyogRW5hYmxlIGJlbGwgYW5kIHNldCB2b2x1bWUgKi8KCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9CRUxMKTsKCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+YmVsbF92b2x1bWUpKTsKCgkvKiBFbmFibGUvZGlzYWJsZSBrZXljbGljayAoYW5kIHBvc3NpYmx5IHNldCB2b2x1bWUpICovCglpZiAodGVzdF9iaXQgKFNORF9DTElDSywgbGstPmRldi0+c25kKSkgewoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgTEtfQ01EX0VOQUJMRV9LRVlDTElDSyk7CgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCB2b2x1bWVfdG9faHcgKGxrLT5rZXljbGlja192b2x1bWUpKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9FTkFCTEVfQ1RSQ0xJQ0spOwoJCWxrLT5zZXJpby0+d3JpdGUgKGxrLT5zZXJpbywgdm9sdW1lX3RvX2h3IChsay0+Y3RybGNsaWNrX3ZvbHVtZSkpOwoJfSBlbHNlIHsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9ESVNBQkxFX0tFWUNMSUNLKTsKCQlsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9ESVNBQkxFX0NUUkNMSUNLKTsKCX0KCgkvKiBTb3VuZCB0aGUgYmVsbCBpZiBuZWVkZWQgKi8KCWlmICh0ZXN0X2JpdCAoU05EX0JFTEwsIGxrLT5kZXYtPnNuZCkpCgkJbGstPnNlcmlvLT53cml0ZSAobGstPnNlcmlvLCBMS19DTURfU09VTkRfQkVMTCk7Cn0KCi8qCiAqIGxra2JkX2Nvbm5lY3QoKSBwcm9iZXMgZm9yIGEgTEsga2V5Ym9hcmQgYW5kIGZpbGxzIHRoZSBuZWNlc3Nhcnkgc3RydWN0dXJlcy4KICovCnN0YXRpYyBpbnQKbGtrYmRfY29ubmVjdCAoc3RydWN0IHNlcmlvICpzZXJpbywgc3RydWN0IHNlcmlvX2RyaXZlciAqZHJ2KQp7CglzdHJ1Y3QgbGtrYmQgKmxrOwoJc3RydWN0IGlucHV0X2RldiAqaW5wdXRfZGV2OwoJaW50IGk7CglpbnQgZXJyOwoKCWxrID0ga3phbGxvYyAoc2l6ZW9mIChzdHJ1Y3QgbGtrYmQpLCBHRlBfS0VSTkVMKTsKCWlucHV0X2RldiA9IGlucHV0X2FsbG9jYXRlX2RldmljZSAoKTsKCWlmICghbGsgfHwgIWlucHV0X2RldikgewoJCWVyciA9IC1FTk9NRU07CgkJZ290byBmYWlsOwoJfQoKCWxrLT5zZXJpbyA9IHNlcmlvOwoJbGstPmRldiA9IGlucHV0X2RldjsKCUlOSVRfV09SSyAoJmxrLT50cSwgbGtrYmRfcmVpbml0LCBsayk7Cglsay0+YmVsbF92b2x1bWUgPSBiZWxsX3ZvbHVtZTsKCWxrLT5rZXljbGlja192b2x1bWUgPSBrZXljbGlja192b2x1bWU7Cglsay0+Y3RybGNsaWNrX3ZvbHVtZSA9IGN0cmxjbGlja192b2x1bWU7CgltZW1jcHkgKGxrLT5rZXljb2RlLCBsa2tiZF9rZXljb2RlLCBzaXplb2YgKGxrX2tleWNvZGVfdCkgKiBMS19OVU1fS0VZQ09ERVMpOwoKCXN0cmxjcHkgKGxrLT5uYW1lLCAiREVDIExLIGtleWJvYXJkIiwgc2l6ZW9mKGxrLT5uYW1lKSk7CglzbnByaW50ZiAobGstPnBoeXMsIHNpemVvZihsay0+cGh5cyksICIlcy9pbnB1dDAiLCBzZXJpby0+cGh5cyk7CgoJaW5wdXRfZGV2LT5uYW1lID0gbGstPm5hbWU7CglpbnB1dF9kZXYtPnBoeXMgPSBsay0+cGh5czsKCWlucHV0X2Rldi0+aWQuYnVzdHlwZSA9IEJVU19SUzIzMjsKCWlucHV0X2Rldi0+aWQudmVuZG9yID0gU0VSSU9fTEtLQkQ7CglpbnB1dF9kZXYtPmlkLnByb2R1Y3QgPSAwOwoJaW5wdXRfZGV2LT5pZC52ZXJzaW9uID0gMHgwMTAwOwoJaW5wdXRfZGV2LT5jZGV2LmRldiA9ICZzZXJpby0+ZGV2OwoJaW5wdXRfZGV2LT5ldmVudCA9IGxra2JkX2V2ZW50OwoJaW5wdXRfZGV2LT5wcml2YXRlID0gbGs7CgoJc2V0X2JpdCAoRVZfS0VZLCBpbnB1dF9kZXYtPmV2Yml0KTsKCXNldF9iaXQgKEVWX0xFRCwgaW5wdXRfZGV2LT5ldmJpdCk7CglzZXRfYml0IChFVl9TTkQsIGlucHV0X2Rldi0+ZXZiaXQpOwoJc2V0X2JpdCAoRVZfUkVQLCBpbnB1dF9kZXYtPmV2Yml0KTsKCXNldF9iaXQgKExFRF9DQVBTTCwgaW5wdXRfZGV2LT5sZWRiaXQpOwoJc2V0X2JpdCAoTEVEX1NMRUVQLCBpbnB1dF9kZXYtPmxlZGJpdCk7CglzZXRfYml0IChMRURfQ09NUE9TRSwgaW5wdXRfZGV2LT5sZWRiaXQpOwoJc2V0X2JpdCAoTEVEX1NDUk9MTEwsIGlucHV0X2Rldi0+bGVkYml0KTsKCXNldF9iaXQgKFNORF9CRUxMLCBpbnB1dF9kZXYtPnNuZGJpdCk7CglzZXRfYml0IChTTkRfQ0xJQ0ssIGlucHV0X2Rldi0+c25kYml0KTsKCglpbnB1dF9kZXYtPmtleWNvZGUgPSBsay0+a2V5Y29kZTsKCWlucHV0X2Rldi0+a2V5Y29kZXNpemUgPSBzaXplb2YgKGxrX2tleWNvZGVfdCk7CglpbnB1dF9kZXYtPmtleWNvZGVtYXggPSBMS19OVU1fS0VZQ09ERVM7Cglmb3IgKGkgPSAwOyBpIDwgTEtfTlVNX0tFWUNPREVTOyBpKyspCgkJc2V0X2JpdCAobGstPmtleWNvZGVbaV0sIGlucHV0X2Rldi0+a2V5Yml0KTsKCglzZXJpb19zZXRfZHJ2ZGF0YSAoc2VyaW8sIGxrKTsKCgllcnIgPSBzZXJpb19vcGVuIChzZXJpbywgZHJ2KTsKCWlmIChlcnIpCgkJZ290byBmYWlsOwoKCWlucHV0X3JlZ2lzdGVyX2RldmljZSAobGstPmRldik7Cglsay0+c2VyaW8tPndyaXRlIChsay0+c2VyaW8sIExLX0NNRF9QT1dFUkNZQ0xFX1JFU0VUKTsKCglyZXR1cm4gMDsKCiBmYWlsOglzZXJpb19zZXRfZHJ2ZGF0YSAoc2VyaW8sIE5VTEwpOwoJaW5wdXRfZnJlZV9kZXZpY2UgKGlucHV0X2Rldik7CglrZnJlZSAobGspOwoJcmV0dXJuIGVycjsKfQoKLyoKICogbGtrYmRfZGlzY29ubmVjdCgpIHVucmVnaXN0ZXJzIGFuZCBjbG9zZXMgYmVoaW5kIHVzLgogKi8Kc3RhdGljIHZvaWQKbGtrYmRfZGlzY29ubmVjdCAoc3RydWN0IHNlcmlvICpzZXJpbykKewoJc3RydWN0IGxra2JkICpsayA9IHNlcmlvX2dldF9kcnZkYXRhIChzZXJpbyk7CgoJaW5wdXRfZ2V0X2RldmljZSAobGstPmRldik7CglpbnB1dF91bnJlZ2lzdGVyX2RldmljZSAobGstPmRldik7CglzZXJpb19jbG9zZSAoc2VyaW8pOwoJc2VyaW9fc2V0X2RydmRhdGEgKHNlcmlvLCBOVUxMKTsKCWlucHV0X3B1dF9kZXZpY2UgKGxrLT5kZXYpOwoJa2ZyZWUgKGxrKTsKfQoKc3RhdGljIHN0cnVjdCBzZXJpb19kZXZpY2VfaWQgbGtrYmRfc2VyaW9faWRzW10gPSB7Cgl7CgkJLnR5cGUJPSBTRVJJT19SUzIzMiwKCQkucHJvdG8JPSBTRVJJT19MS0tCRCwKCQkuaWQJPSBTRVJJT19BTlksCgkJLmV4dHJhCT0gU0VSSU9fQU5ZLAoJfSwKCXsgMCB9Cn07CgpNT0RVTEVfREVWSUNFX1RBQkxFKHNlcmlvLCBsa2tiZF9zZXJpb19pZHMpOwoKc3RhdGljIHN0cnVjdCBzZXJpb19kcml2ZXIgbGtrYmRfZHJ2ID0gewoJLmRyaXZlcgkJPSB7CgkJLm5hbWUJPSAibGtrYmQiLAoJfSwKCS5kZXNjcmlwdGlvbgk9IERSSVZFUl9ERVNDLAoJLmlkX3RhYmxlCT0gbGtrYmRfc2VyaW9faWRzLAoJLmNvbm5lY3QJPSBsa2tiZF9jb25uZWN0LAoJLmRpc2Nvbm5lY3QJPSBsa2tiZF9kaXNjb25uZWN0LAoJLmludGVycnVwdAk9IGxra2JkX2ludGVycnVwdCwKfTsKCi8qCiAqIFRoZSBmdW5jdGlvbnMgZm9yIGluc2VyaW5nL3JlbW92aW5nIHVzIGFzIGEgbW9kdWxlLgogKi8Kc3RhdGljIGludCBfX2luaXQKbGtrYmRfaW5pdCAodm9pZCkKewoJc2VyaW9fcmVnaXN0ZXJfZHJpdmVyKCZsa2tiZF9kcnYpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdApsa2tiZF9leGl0ICh2b2lkKQp7CglzZXJpb191bnJlZ2lzdGVyX2RyaXZlcigmbGtrYmRfZHJ2KTsKfQoKbW9kdWxlX2luaXQgKGxra2JkX2luaXQpOwptb2R1bGVfZXhpdCAobGtrYmRfZXhpdCk7Cgo=