LyoKICAgIFNETCAtIFNpbXBsZSBEaXJlY3RNZWRpYSBMYXllcgogICAgQ29weXJpZ2h0IChDKSAxOTk3LTIwMTIgU2FtIExhbnRpbmdhCgogICAgVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKICAgIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogICAgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICAgIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogICAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAgICBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGlicmFyeSBHZW5lcmFsIFB1YmxpYwogICAgTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZQogICAgRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQoKICAgIFNhbSBMYW50aW5nYQogICAgc2xvdWtlbkBsaWJzZGwub3JnCiovCiNpbmNsdWRlICJTRExfY29uZmlnLmgiCgovKgogICAgIEZpbGUgYWRkZWQgYnkgQWxhbiBCdWNrbGV5IChhbGFuX2JhYUBob3RtYWlsLmNvbSkgZm9yIFJJU0MgT1MgY29tcGF0YWJpbGl0eQoJIDI3IE1hcmNoIDIwMDMKCiAgICAgSW1wbGVtZW50cyBrZXlib2FyZCBzZXR1cCwgZXZlbnQgcHVtcCBhbmQga2V5Ym9hcmQgYW5kIG1vdXNlIHBvbGxpbmcKKi8KCgojaW5jbHVkZSAiU0RMLmgiCiNpbmNsdWRlICIuLi8uLi90aW1lci9TRExfdGltZXJfYy5oIgojaW5jbHVkZSAiLi4vLi4vZXZlbnRzL1NETF9zeXNldmVudHMuaCIKI2luY2x1ZGUgIi4uLy4uL2V2ZW50cy9TRExfZXZlbnRzX2MuaCIKI2luY2x1ZGUgIi4uL1NETF9jdXJzb3JfYy5oIgojaW5jbHVkZSAiU0RMX3Jpc2Nvc3ZpZGVvLmgiCiNpbmNsdWRlICJTRExfcmlzY29zZXZlbnRzX2MuaCIKCiNpbmNsdWRlICJtZW1vcnkuaCIKI2luY2x1ZGUgInN0ZGxpYi5oIgojaW5jbHVkZSAiY3R5cGUuaCIKCiNpbmNsdWRlICJrZXJuZWwuaCIKI2luY2x1ZGUgInN3aXMuaCIKCi8qIFRoZSB0cmFuc2xhdGlvbiB0YWJsZSBmcm9tIGEgUklTQyBPUyBpbnRlcm5hbCBrZXkgbnVtYmVycyB0byBhIFNETCBrZXlzeW0gKi8Kc3RhdGljIFNETEtleSBST19rZXltYXBbU0RMS19MQVNUXTsKCi8qIFJJU0MgT1MgS2V5IGNvZGVzICovCiNkZWZpbmUgUk9LRVlfU0hJRlQgMAojZGVmaW5lIFJPS0VZX0NUUkwgIDEKI2RlZmluZSBST0tFWV9BTFQgICAyCi8qIExlZnQgc2hpZnQgaXMgZmlyc3Qga2V5IHdlIHdpbGwgY2hlY2sgZm9yICovCiNkZWZpbmUgUk9LRVlfTEVGVF9TSElGVCAzCgovKiBOZWVkIHRvIGlnbm9yZSBtb3VzZSBidXR0b25zIGFzIHRoZXkgYXJlIHByb2Nlc3NlZCBzZXBhcmF0ZWx5ICovCiNkZWZpbmUgUk9LRVlfTEVGVF9NT1VTRSAgIDkKI2RlZmluZSBST0tFWV9DRU5UUkVfTU9VU0UgMTAKI2RlZmluZSBST0tFWV9SSUdIVF9NT1VTRSAgMTEKCi8qIE5vIGtleSBoYXMgYmVlbiBwcmVzc2VkIHJldHVybiB2YWx1ZSovCiNkZWZpbmUgUk9LRVlfTk9ORSAyNTUKCi8qIElkIG9mIGxhc3Qga2V5IGluIGtleWJvYXJkICovCiNkZWZpbmUgUk9LRVlfTEFTVF9LRVkgIDEyNAoKLyogU2l6ZSBvZiBhcnJheSBmb3IgYWxsIGtleXMgKi8KI2RlZmluZSBST0tFWUJEX0FSUkFZU0laRSAxMjUKCnN0YXRpYyBjaGFyIFJPX3ByZXNzZWRbUk9LRVlCRF9BUlJBWVNJWkVdOwoKc3RhdGljIFNETF9rZXlzeW0gKlRyYW5zbGF0ZUtleShpbnQgaW50a2V5LCBTRExfa2V5c3ltICprZXlzeW0sIGludCBwcmVzc2VkKTsKCnZvaWQgUklTQ09TX1BvbGxNb3VzZShfVEhJUyk7CnZvaWQgUklTQ09TX1BvbGxLZXlib2FyZCgpOwoKdm9pZCBSSVNDT1NfUG9sbE1vdXNlSGVscGVyKF9USElTLCBpbnQgZnVsbHNjcmVlbik7CgojaWYgU0RMX1RIUkVBRFNfRElTQUJMRUQKZXh0ZXJuIHZvaWQgRFJlbmRlcmVyX0ZpbGxCdWZmZXJzKCk7CgovKiBUaW1lciBydW5uaW5nIGZ1bmN0aW9uICovCmV4dGVybiB2b2lkIFJJU0NPU19DaGVja1RpbWVyKCk7CgojZW5kaWYKCnZvaWQgRlVMTFNDUkVFTl9QdW1wRXZlbnRzKF9USElTKQp7CiAgICAvKiBDdXJyZW50IGltcGxlbWVudGF0aW9uIHJlcXVpcmVzIGtleWJvYXJkIGFuZCBtb3VzZSBwb2xsaW5nICovCglSSVNDT1NfUG9sbEtleWJvYXJkKCk7CglSSVNDT1NfUG9sbE1vdXNlKHRoaXMpOwojaWYgU0RMX1RIUkVBRFNfRElTQUJMRUQKLy8JRFJlbmRlcmVyX0ZpbGxCdWZmZXJzKCk7CglpZiAoU0RMX3RpbWVyX3J1bm5pbmcpIFJJU0NPU19DaGVja1RpbWVyKCk7CiNlbmRpZgp9CgoKdm9pZCBSSVNDT1NfSW5pdE9TS2V5bWFwKF9USElTKQp7CglpbnQgaTsKCgkvKiBNYXAgdGhlIFZLIGtleXN5bXMgKi8KCWZvciAoIGk9MDsgaTxTRExfYXJyYXlzaXplKFJPX2tleW1hcCk7ICsraSApCgkJUk9fa2V5bWFwW2ldID0gU0RMS19VTktOT1dOOwoKICBST19rZXltYXBbM10gPSBTRExLX0xTSElGVDsKICBST19rZXltYXBbNF0gPSBTRExLX0xDVFJMOwogIFJPX2tleW1hcFs1XSA9IFNETEtfTEFMVDsKICBST19rZXltYXBbNl0gPSBTRExLX1JTSElGVDsKICBST19rZXltYXBbN10gPSBTRExLX1JDVFJMOwogIFJPX2tleW1hcFs4XSA9IFNETEtfUkFMVDsKICBST19rZXltYXBbMTZdID0gU0RMS19xOwogIFJPX2tleW1hcFsxN10gPSBTRExLXzM7CiAgUk9fa2V5bWFwWzE4XSA9IFNETEtfNDsKICBST19rZXltYXBbMTldID0gU0RMS181OwogIFJPX2tleW1hcFsyMF0gPSBTRExLX0Y0OwogIFJPX2tleW1hcFsyMV0gPSBTRExLXzg7CiAgUk9fa2V5bWFwWzIyXSA9IFNETEtfRjc7CiAgUk9fa2V5bWFwWzIzXSA9IFNETEtfTUlOVVMsCiAgUk9fa2V5bWFwWzI1XSA9IFNETEtfTEVGVDsKICBST19rZXltYXBbMjZdID0gU0RMS19LUDY7CiAgUk9fa2V5bWFwWzI3XSA9IFNETEtfS1A3OwogIFJPX2tleW1hcFsyOF0gPSBTRExLX0YxMTsKICBST19rZXltYXBbMjldID0gU0RMS19GMTI7CiAgUk9fa2V5bWFwWzMwXSA9IFNETEtfRjEwOwogIFJPX2tleW1hcFszMV0gPSBTRExLX1NDUk9MTE9DSzsKICBST19rZXltYXBbMzJdID0gU0RMS19QUklOVDsKICBST19rZXltYXBbMzNdID0gU0RMS193OwogIFJPX2tleW1hcFszNF0gPSBTRExLX2U7CiAgUk9fa2V5bWFwWzM1XSA9IFNETEtfdDsKICBST19rZXltYXBbMzZdID0gU0RMS183OwogIFJPX2tleW1hcFszN10gPSBTRExLX2k7CiAgUk9fa2V5bWFwWzM4XSA9IFNETEtfOTsKICBST19rZXltYXBbMzldID0gU0RMS18wOwogIFJPX2tleW1hcFs0MV0gPSBTRExLX0RPV047CiAgUk9fa2V5bWFwWzQyXSA9IFNETEtfS1A4OwogIFJPX2tleW1hcFs0M10gPSBTRExLX0tQOTsKICBST19rZXltYXBbNDRdID0gU0RMS19CUkVBSzsKICBST19rZXltYXBbNDVdID0gU0RMS19CQUNLUVVPVEU7Ci8qICBST19rZXltYXBbNDZdID0gU0RMS19jdXJyZW5jeTsgVE9ETzogRmlndXJlIG91dCBpZiB0aGlzIGhhcyBhIHZhbHVlICovCiAgUk9fa2V5bWFwWzQ3XSA9IFNETEtfQkFDS1NQQUNFOwogIFJPX2tleW1hcFs0OF0gPSBTRExLXzE7CiAgUk9fa2V5bWFwWzQ5XSA9IFNETEtfMjsKICBST19rZXltYXBbNTBdID0gU0RMS19kOwogIFJPX2tleW1hcFs1MV0gPSBTRExLX3I7CiAgUk9fa2V5bWFwWzUyXSA9IFNETEtfNjsKICBST19rZXltYXBbNTNdID0gU0RMS191OwogIFJPX2tleW1hcFs1NF0gPSBTRExLX287CiAgUk9fa2V5bWFwWzU1XSA9IFNETEtfcDsKICBST19rZXltYXBbNTZdID0gU0RMS19MRUZUQlJBQ0tFVDsKICBST19rZXltYXBbNTddID0gU0RMS19VUDsKICBST19rZXltYXBbNThdID0gU0RMS19LUF9QTFVTOwogIFJPX2tleW1hcFs1OV0gPSBTRExLX0tQX01JTlVTOwogIFJPX2tleW1hcFs2MF0gPSBTRExLX0tQX0VOVEVSOwogIFJPX2tleW1hcFs2MV0gPSBTRExLX0lOU0VSVDsKICBST19rZXltYXBbNjJdID0gU0RMS19IT01FOwogIFJPX2tleW1hcFs2M10gPSBTRExLX1BBR0VVUDsKICBST19rZXltYXBbNjRdID0gU0RMS19DQVBTTE9DSzsKICBST19rZXltYXBbNjVdID0gU0RMS19hOwogIFJPX2tleW1hcFs2Nl0gPSBTRExLX3g7CiAgUk9fa2V5bWFwWzY3XSA9IFNETEtfZjsKICBST19rZXltYXBbNjhdID0gU0RMS195OwogIFJPX2tleW1hcFs2OV0gPSBTRExLX2o7CiAgUk9fa2V5bWFwWzcwXSA9IFNETEtfazsKICBST19rZXltYXBbNzJdID0gU0RMS19TRU1JQ09MT047CiAgUk9fa2V5bWFwWzczXSA9IFNETEtfUkVUVVJOOwogIFJPX2tleW1hcFs3NF0gPSBTRExLX0tQX0RJVklERTsKICBST19rZXltYXBbNzZdID0gU0RMS19LUF9QRVJJT0Q7CiAgUk9fa2V5bWFwWzc3XSA9IFNETEtfTlVNTE9DSzsKICBST19rZXltYXBbNzhdID0gU0RMS19QQUdFRE9XTjsKICBST19rZXltYXBbNzldID0gU0RMS19RVU9URTsKICBST19rZXltYXBbODFdID0gU0RMS19zOwogIFJPX2tleW1hcFs4Ml0gPSBTRExLX2M7CiAgUk9fa2V5bWFwWzgzXSA9IFNETEtfZzsKICBST19rZXltYXBbODRdID0gU0RMS19oOwogIFJPX2tleW1hcFs4NV0gPSBTRExLX247CiAgUk9fa2V5bWFwWzg2XSA9IFNETEtfbDsKICBST19rZXltYXBbODddID0gU0RMS19TRU1JQ09MT047CiAgUk9fa2V5bWFwWzg4XSA9IFNETEtfUklHSFRCUkFDS0VUOwogIFJPX2tleW1hcFs4OV0gPSBTRExLX0RFTEVURTsKICBST19rZXltYXBbOTBdID0gU0RMS19LUF9NSU5VUzsKICBST19rZXltYXBbOTFdID0gU0RMS19LUF9NVUxUSVBMWTsKICBST19rZXltYXBbOTNdID0gU0RMS19FUVVBTFM7CiAgUk9fa2V5bWFwWzk0XSA9IFNETEtfQkFDS1NMQVNIOwogIFJPX2tleW1hcFs5Nl0gPSBTRExLX1RBQjsKICBST19rZXltYXBbOTddID0gU0RMS196OwogIFJPX2tleW1hcFs5OF0gPSBTRExLX1NQQUNFOwogIFJPX2tleW1hcFs5OV0gPSBTRExLX3Y7CiAgUk9fa2V5bWFwWzEwMF0gPSBTRExLX2I7CiAgUk9fa2V5bWFwWzEwMV0gPSBTRExLX207CiAgUk9fa2V5bWFwWzEwMl0gPSBTRExLX0NPTU1BOwogIFJPX2tleW1hcFsxMDNdID0gU0RMS19QRVJJT0Q7CiAgUk9fa2V5bWFwWzEwNF0gPSBTRExLX1NMQVNIOwogIFJPX2tleW1hcFsxMDVdID0gU0RMS19FTkQ7CiAgUk9fa2V5bWFwWzEwNl0gPSBTRExLX0tQMDsKICBST19rZXltYXBbMTA3XSA9IFNETEtfS1AxOwogIFJPX2tleW1hcFsxMDhdID0gU0RMS19LUDM7CiAgUk9fa2V5bWFwWzExMl0gPSBTRExLX0VTQ0FQRTsKICBST19rZXltYXBbMTEzXSA9IFNETEtfRjE7CiAgUk9fa2V5bWFwWzExNF0gPSBTRExLX0YyOwogIFJPX2tleW1hcFsxMTVdID0gU0RMS19GMzsKICBST19rZXltYXBbMTE2XSA9IFNETEtfRjU7CiAgUk9fa2V5bWFwWzExN10gPSBTRExLX0Y2OwogIFJPX2tleW1hcFsxMThdID0gU0RMS19GODsKICBST19rZXltYXBbMTE5XSA9IFNETEtfRjk7CiAgUk9fa2V5bWFwWzEyMF0gPSBTRExLX0hBU0g7CiAgUk9fa2V5bWFwWzEyMV0gPSBTRExLX1JJR0hUOwogIFJPX2tleW1hcFsxMjJdID0gU0RMS19LUDQ7CiAgUk9fa2V5bWFwWzEyM10gPSBTRExLX0tQNTsKICBST19rZXltYXBbMTI0XSA9IFNETEtfS1AyOwoKICBTRExfbWVtc2V0KFJPX3ByZXNzZWQsIDAsIFJPS0VZQkRfQVJSQVlTSVpFKTsKfQoKCi8qIFZhcmlhYmxlIGZvciBtb3VzZSByZWxhdGl2ZSBwcm9jZXNzaW5nICovCmludCBtb3VzZV9yZWxhdGl2ZSA9IDA7CgovKiBDaGVjayB0byBzZWUgaWYgd2UgbmVlZCB0byBlbnRlciBvciBsZWF2ZSBtb3VzZSByZWxhdGl2ZSBtb2RlICovCgp2b2lkIFJJU0NPU19DaGVja01vdXNlTW9kZShfVEhJUykKewogICAgLyogSWYgdGhlIG1vdXNlIGlzIGhpZGRlbiBhbmQgaW5wdXQgaXMgZ3JhYmJlZCwgd2UgdXNlIHJlbGF0aXZlIG1vZGUgKi8KICAgIGlmICggIShTRExfY3Vyc29yc3RhdGUgJiBDVVJTT1JfVklTSUJMRSkgJiYKICAgICAgICAodGhpcy0+aW5wdXRfZ3JhYiAhPSBTRExfR1JBQl9PRkYpICkgewogICAgICAgICAgICBtb3VzZV9yZWxhdGl2ZSA9IDE7CiAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbW91c2VfcmVsYXRpdmUgPSAwOwogICAgIH0KfQoKCnZvaWQgUklTQ09TX1BvbGxNb3VzZShfVEhJUykKewogICBSSVNDT1NfUG9sbE1vdXNlSGVscGVyKHRoaXMsIDEpOwp9CgpleHRlcm4gaW50IG1vdXNlSW5XaW5kb3c7Cgp2b2lkIFdJTVBfUG9sbE1vdXNlKF9USElTKQp7CiAgIC8qIE9ubHkgcG9sbCB3aGVuIG1vdXNlIGlzIG92ZXIgdGhlIHdpbmRvdyAqLwogICBpZiAoIW1vdXNlSW5XaW5kb3cpIHJldHVybjsKCiAgIFJJU0NPU19Qb2xsTW91c2VIZWxwZXIodGhpcywgMCk7Cn0KCi8qIFN0YXRpYyB2YXJpYWJsZXMgc28gb25seSBjaGFuZ2VzIGFyZSByZXBvcnRlZCAqLwpzdGF0aWMgU2ludDE2IGxhc3RfeCA9IC0xLCBsYXN0X3kgPSAtMTsKc3RhdGljIGludCBsYXN0X2J1dHRvbnMgPSAwOwoKLyogU2hhcmUgcm91dGluZSBiZXR3ZWVuIFdJTVAgYW5kIEZVTExTQ1JFRU4gZm9yIHBvbGxpbmcgbW91c2UgYW5kCiAgIHBhc3Npbmcgb24gZXZlbnRzICovCnZvaWQgUklTQ09TX1BvbGxNb3VzZUhlbHBlcihfVEhJUywgaW50IGZ1bGxzY3JlZW4pCnsKICAgIF9rZXJuZWxfc3dpX3JlZ3MgcmVnczsKICAgIHN0YXRpYyBpbnQgc3RhcnRpbmcgPSAxOwoKICAgIGlmIChfa2VybmVsX3N3aShPU19Nb3VzZSwgJnJlZ3MsICZyZWdzKSA9PSBOVUxMKQogICAgewogICAgICAgU2ludDE2IG5ld194ID0gcmVncy5yWzBdOyAvKiBJbml0aWFseSBnZXQgYXMgT1MgdW5pdHMgKi8KICAgICAgIFNpbnQxNiBuZXdfeSA9IHJlZ3MuclsxXTsKCiAgICAgICAvKiBEaXNjYXJkIG1vdXNlIGV2ZW50cyB1bnRpbCB0aGV5IGxldCBnbyBvZiB0aGUgbW91c2UgYWZ0ZXIgc3RhcnRpbmcgKi8KICAgICAgIGlmIChzdGFydGluZyAmJiByZWdzLnJbMl0gIT0gMCkKICAgICAgICAgcmV0dXJuOwogICAgICAgZWxzZQogICAgICAgICBzdGFydGluZyA9IDA7CgogICAgICAgaWYgKG5ld194ICE9IGxhc3RfeCB8fCBuZXdfeSAhPSBsYXN0X3kgfHwgbGFzdF9idXR0b25zICE9IHJlZ3MuclsyXSkKICAgICAgIHsKICAgICAgICAgIC8qIFNvbWV0aGluZyBjaGFuZ2VkIHNvIGdlbmVyYXRlIGFwcHJvcHJpYXRlIGV2ZW50cyAqLwogICAgICAgICAgaW50IHRvcExlZnRYLCB0b3BMZWZ0WTsgIC8qIFRvcCBsZWZ0IE9TIHVuaXRzICovCiAgICAgICAgICBpbnQgeCwgeTsgICAgICAgICAgICAgICAgLyogTW91c2UgcG9zaXRpb24gaW4gU0RMIHBpeGVscyAqLwoKICAgICAgICAgIGlmIChmdWxsc2NyZWVuKQogICAgICAgICAgewogICAgICAgICAgICAgdG9wTGVmdFggPSAwOwogICAgICAgICAgICAgdG9wTGVmdFkgPSAodGhpcy0+aGlkZGVuLT5oZWlnaHQgPDwgdGhpcy0+aGlkZGVuLT55ZWlnKSAtIDE7CiAgICAgICAgICB9IGVsc2UKICAgICAgICAgIHsKICAgICAgICAgICAgIGludCB3aW5kb3dfc3RhdGVbOV07CgoJICAgICAgICAgLyogR2V0IGN1cnJlbnQgd2luZG93IHN0YXRlICovCgkJICAgICB3aW5kb3dfc3RhdGVbMF0gPSB0aGlzLT5oaWRkZW4tPndpbmRvd19oYW5kbGU7CgkJICAgICByZWdzLnJbMV0gPSAodW5zaWduZWQgaW50KXdpbmRvd19zdGF0ZTsKCQkgICAgIF9rZXJuZWxfc3dpKFdpbXBfR2V0V2luZG93U3RhdGUsICZyZWdzLCAmcmVncyk7CgogICAgICAgICAgICAgdG9wTGVmdFggPSB3aW5kb3dfc3RhdGVbMV07CiAgICAgICAgICAgICB0b3BMZWZ0WSA9IHdpbmRvd19zdGF0ZVs0XTsKICAgICAgICAgIH0KCgkJICAvKiBDb252ZXJ0IGNvLW9yZGluYXRlcyB0byB3b3Jrc3BhY2UgKi8KCQkgIHggPSBuZXdfeCAtIHRvcExlZnRYOwogICAgICAgICAgeSA9IHRvcExlZnRZIC0gbmV3X3k7IC8qIFkgZ29lcyBmcm9tIHRvcCBvZiB3aW5kb3cvc2NyZWVuICovCgoJIAkgIC8qIENvbnZlcnQgT1MgdW5pdHMgdG8gcGl4ZWxzICovCgkgICAgICB4ID4+PSB0aGlzLT5oaWRkZW4tPnhlaWc7CgkJICB5ID4+PSB0aGlzLT5oaWRkZW4tPnllaWc7CgogICAgICAgICAgaWYgKGxhc3RfeCAhPSBuZXdfeCB8fCBsYXN0X3kgIT0gbmV3X3kpCiAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAobW91c2VfcmVsYXRpdmUpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgY2VudHJlX3ggPSBTRExfVmlkZW9TdXJmYWNlLT53LzI7CiAgICAgICAgICAgICAgICBpbnQgY2VudHJlX3kgPSBTRExfVmlkZW9TdXJmYWNlLT5oLzI7CgogICAgICAgICAgICAgICAgaWYgKGNlbnRyZV94ICE9IHggfHwgY2VudHJlX3kgIT0geSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIGlmIChTRExfVmlkZW9TdXJmYWNlKSBTRExfUHJpdmF0ZU1vdXNlTW90aW9uKDAsMSx4IC0gY2VudHJlX3gsIHkgLSBjZW50cmVfeSk7CiAgICAgICAgICAgICAgICAgICBsYXN0X3ggPSB0b3BMZWZ0WCArIChjZW50cmVfeCA8PCB0aGlzLT5oaWRkZW4tPnhlaWcpOwogICAgICAgICAgICAgICAgICAgbGFzdF95ID0gdG9wTGVmdFkgLSAoY2VudHJlX3kgPDwgdGhpcy0+aGlkZGVuLT55ZWlnKTsKCiAgICAgICAgICAgICAgICAgICAvKiBSZS1jZW50cmUgdGhlIG1vdXNlIHBvaW50ZXIsIHNvIHdlIHN0aWxsIGdldCByZWxhdGl2ZQogICAgICAgICAgICAgICAgICAgICAgbW92ZW1lbnQgd2hlbiB0aGUgbW91c2UgaXMgYXQgdGhlIGVkZ2Ugb2YgdGhlIHdpbmRvdwogICAgICAgICAgICAgICAgICAgICAgb3Igc2NyZWVuLgogICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgYmxvY2tbNV07CgogICAgICAgICAgICAgICAgICAgICAgYmxvY2tbMF0gPSAzOyAvKiBPU1dPUkQgbW92ZSBwb2ludGVyIHN1Yi1yZWFzb24gY29kZSAqLwogICAgICAgICAgICAgICAgICAgICAgYmxvY2tbMV0gPSBsYXN0X3ggJiAweEZGOwogICAgICAgICAgICAgICAgICAgICAgYmxvY2tbMl0gPSAobGFzdF94ID4+IDgpICYgMHhGRjsKICAgICAgICAgICAgICAgICAgICAgIGJsb2NrWzNdID0gbGFzdF95ICYgMHhGRjsKICAgICAgICAgICAgICAgICAgICAgIGJsb2NrWzRdID0gKGxhc3RfeSA+PiA4KSAmIDB4RkY7CiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICByZWdzLnJbMF0gPSAyMTsgLyogT1NXT1JEIHBvaW50ZXIgc3R1ZmYgY29kZSAqLwogICAgICAgICAgICAgICAgICAgICAgcmVncy5yWzFdID0gKGludClibG9jazsKICAgICAgICAgICAgICAgICAgICAgIF9rZXJuZWxfc3dpKE9TX1dvcmQsICZyZWdzLCAmcmVncyk7CiAgICAgICAgICAgICAgIAkgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxhc3RfeCA9IG5ld194OwogICAgICAgICAgICAgICAgbGFzdF95ID0gbmV3X3k7CiAgICAgICAgICAgICAgICBTRExfUHJpdmF0ZU1vdXNlTW90aW9uKDAsMCx4LHkpOwogICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIGlmIChsYXN0X2J1dHRvbnMgIT0gcmVncy5yWzJdKQogICAgICAgICAgewogICAgICAgICAgICAgaW50IGNoYW5nZWQgPSBsYXN0X2J1dHRvbnMgXiByZWdzLnJbMl07CiAgICAgICAgICAgICBsYXN0X2J1dHRvbnMgPSByZWdzLnJbMl07CiAgICAgICAgICAgICBpZiAoY2hhbmdlZCAmIDQpIFNETF9Qcml2YXRlTW91c2VCdXR0b24oKGxhc3RfYnV0dG9ucyAmIDQpID8gU0RMX1BSRVNTRUQgOiBTRExfUkVMRUFTRUQsIFNETF9CVVRUT05fTEVGVCwgMCwgMCk7CiAgICAgICAgICAgICBpZiAoY2hhbmdlZCAmIDIpIFNETF9Qcml2YXRlTW91c2VCdXR0b24oKGxhc3RfYnV0dG9ucyAmIDIpID8gU0RMX1BSRVNTRUQgOiBTRExfUkVMRUFTRUQsIFNETF9CVVRUT05fTUlERExFLCAwLCAwKTsKICAgICAgICAgICAgIGlmIChjaGFuZ2VkICYgMSkgU0RMX1ByaXZhdGVNb3VzZUJ1dHRvbigobGFzdF9idXR0b25zICYgMSkgPyBTRExfUFJFU1NFRCA6IFNETF9SRUxFQVNFRCwgU0RMX0JVVFRPTl9SSUdIVCwgMCwgMCk7CiAgICAgICAgICB9CiAgICAgICB9CiAgICB9Cn0KCnZvaWQgUklTQ09TX1BvbGxLZXlib2FyZCgpCnsKCWludCB3aGljaF9rZXkgPSBST0tFWV9MRUZUX1NISUZUOwoJaW50IGo7CglpbnQgbWluX2tleSwgbWF4X2tleTsKCVNETF9rZXlzeW0ga2V5OwoKCS8qIFNjYW4gdGhlIGtleWJvYXJkIHRvIHNlZSB3aGF0IGlzIHByZXNzZWQgKi8KCXdoaWxlICh3aGljaF9rZXkgPD0gUk9LRVlfTEFTVF9LRVkpCgl7CgkJd2hpY2hfa2V5ID0gKF9rZXJuZWxfb3NieXRlKDEyMSwgd2hpY2hfa2V5LCAwKSAmIDB4RkYpOwoJICAgIGlmICh3aGljaF9rZXkgIT0gUk9LRVlfTk9ORSkKCSAgICB7CgkJICAgIHN3aXRjaCh3aGljaF9rZXkpCgkJICAgIHsKCQkgICAgLyogU2tpcCBvdmVyIG1vdXNlIGtleXMgKi8KCQkgICAgY2FzZSBST0tFWV9MRUZUX01PVVNFOgoJCSAgICBjYXNlIFJPS0VZX0NFTlRSRV9NT1VTRToKCQkgICAgY2FzZSBST0tFWV9SSUdIVF9NT1VTRToKCQkJCXdoaWNoX2tleSA9IFJPS0VZX1JJR0hUX01PVVNFOwoJCQkJYnJlYWs7CgogICAgICAgICAgICAvKiBJZ25vcmUga2V5cyB0aGF0IGNhdXNlIDIgaW50ZXJuYWwgbnVtYmVyIHRvIGJlIGdlbmVyYXRlZCAqLwoJCQljYXNlIDcxOiBjYXNlIDI0OiBjYXNlIDg3OiBjYXNlIDQwOgoJCQkgICAgYnJlYWs7CgogICAgICAgICAgICAvKiBJZ25vcmUgYnJlYWsgYXMgaXQgY2FuIGJlIGxhdGNoZWQgb24gKi8KICAgICAgICAgICAgY2FzZSA0NDoKICAgICAgICAgICAgICAgIGJyZWFrOwoKCQkJZGVmYXVsdDoKCQkJCVJPX3ByZXNzZWRbd2hpY2hfa2V5XSArPSAyOwoJCQkJYnJlYWs7CgkJICAgIH0KCQkJd2hpY2hfa2V5Kys7CgkJfQoJfQoKCS8qIEdlbmVyYXRlIGtleSByZWxlYXNlZCBtZXNzYWdlcyAqLwoJbWluX2tleSA9IFJPS0VZX0xBU1RfS0VZKzE7CgltYXhfa2V5ID0gUk9LRVlfTEVGVF9TSElGVDsKCglmb3IgKGogPSBST0tFWV9MRUZUX1NISUZUOyBqIDw9IFJPS0VZX0xBU1RfS0VZOyBqKyspCgl7CgkJaWYgKFJPX3ByZXNzZWRbal0pCgkJewoJCQlpZiAoUk9fcHJlc3NlZFtqXSA9PSAxKQoJCQl7CgkJCQlST19wcmVzc2VkW2pdID0gMDsKCQkJCVNETF9Qcml2YXRlS2V5Ym9hcmQoU0RMX1JFTEVBU0VELCBUcmFuc2xhdGVLZXkoaiwma2V5LDApKTsKCQkJfSBlbHNlIAoJCQl7CgkJCQlpZiAoaiA8IG1pbl9rZXkpIG1pbl9rZXkgPSBqOwoJCQkJaWYgKGogPiBtYXhfa2V5KSBtYXhfa2V5ID0gajsKCQkJfQoJCX0KCX0KCgkvKiBHZW5lcmF0ZSBrZXkgcHJlc3NlZCBtZXNzYWdlcyAqLwoJZm9yIChqID0gbWluX2tleTsgaiA8PSBtYXhfa2V5OyBqKyspCgl7CgkJaWYgKFJPX3ByZXNzZWRbal0pCgkJewoJCQlpZiAoUk9fcHJlc3NlZFtqXSA9PSAyKQoJCQl7CgkJCQlTRExfUHJpdmF0ZUtleWJvYXJkKFNETF9QUkVTU0VELFRyYW5zbGF0ZUtleShqLCZrZXksMSkpOwoJCQl9CgkJCVJPX3ByZXNzZWRbal0gPSAxOwoJCX0KCX0KfQoKc3RhdGljIFNETF9rZXlzeW0gKlRyYW5zbGF0ZUtleShpbnQgaW50a2V5LCBTRExfa2V5c3ltICprZXlzeW0sIGludCBwcmVzc2VkKQp7CgkvKiBTZXQgdGhlIGtleXN5bSBpbmZvcm1hdGlvbiAqLwoJa2V5c3ltLT5zY2FuY29kZSA9ICh1bnNpZ25lZCBjaGFyKSBpbnRrZXk7CglrZXlzeW0tPnN5bSA9IFJPX2tleW1hcFtpbnRrZXldOwoJa2V5c3ltLT5tb2QgPSBLTU9EX05PTkU7CglrZXlzeW0tPnVuaWNvZGUgPSAwOwoJaWYgKCBwcmVzc2VkICYmIFNETF9UcmFuc2xhdGVVTklDT0RFICkKCXsKCQlpbnQgc3RhdGU7CgkJaW50IGNoOwoKCQlzdGF0ZSA9IChfa2VybmVsX29zYnl0ZSgyMDIsIDAsIDI1NSkgJiAweEZGKTsKCgkJLypUT0RPOiBUYWtlIGludG8gYWNjb3VudCBvdGhlciBrZXlib2FyZCBsYXlvdXRzICovCgoJCWNoID0ga2V5c3ltLT5zeW07IC8qIFRoaXMgc2hvdWxkIGhhbmRsZSBtb3N0IHVuc2hpZnRlZCBrZXlzICovCgogICAgICAgIGlmIChpbnRrZXkgPCA5IHx8IGNoID09IFNETEtfVU5LTk9XTikKICAgICAgICB7CiAgICAgICAgICAgY2ggPSAwOwoKICAgICAgICB9IGVsc2UgaWYgKHN0YXRlICYgNjQpIC8qIENvbnRyb2wgb24gKi8KCQl7CgkJCWNoID0gY2ggJiAzMTsKCgkJfSBlbHNlIAoJCXsKCQkJaW50IHRvcE9mS2V5ID0gMDsKICAgICAgICAgICAgaWYgKHN0YXRlICYgOCkgLyogU2hpZnQgb24gKi8KCQkJewoJCQkJdG9wT2ZLZXkgPSAxOwoJCQl9CgoJCQlpZiAoKHN0YXRlICYgMTYpID09IDApIC8qIENhcHMgbG9jayBpcyBvbiAqLwoJCQl7CgkJCSAgIGlmIChjaCA+PSBTRExLX2EgJiYgY2ggPD0gU0RMS196KQoJCQkgICB7CiAJCQkJICBpZiAoKHN0YXRlICYgMTI4KSA9PSAwKSAvKiBTaGlmdCBFbmFibGUgb2ZmICovCgkJCQkgIHsKCQkJCSAgICAgLyogQWxsIGxldHRlciBiZWNvbWUgdXBwZXIgY2FzZSAqLwoJCQkJIAkgdG9wT2ZLZXkgPSAxOwoJCQkJICB9IGVsc2UKCQkJCSAgewoJCQkJICAgICAvKiBTaGlmdCtMZXR0ZXJzIGdpdmVzIGxvd2VyIGNhc2UgKi8KCQkJCSAgICAgdG9wT2ZLZXkgPSAxIC0gdG9wT2ZLZXk7CgkJCQkgIH0KCQkgICAgICAgfQoJCQl9CgoJCQlpZiAodG9wT2ZLZXkpCgkJCXsKCQkJCS8qIEtleSBwcm9kdWNlZCB3aXRoIHNoaWZ0IGhlbGQgZG93biAqLwoKCQkJCS8qIExldHRlcnMganVzdCBnaXZlIHVwcGVyIGNhc2UgdmVyc2lvbiAqLwoJCQkJaWYgKGNoID49IFNETEtfYSAmJiBjaCA8PSBTRExLX3opIGNoID0gdG91cHBlcihjaCk7CgkJCQllbHNlCgkJCQl7CgkJCQkJc3dpdGNoKGNoKQoJCQkJCXsKCQkJCQljYXNlIFNETEtfSEFTSDogICBjaCA9ICd+JzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX1FVT1RFOiAgY2ggPSAnQCc7IGJyZWFrOwoJCQkJCWNhc2UgU0RMS19DT01NQTogIGNoID0gJzwnOyBicmVhazsKCQkJCQljYXNlIFNETEtfTUlOVVM6ICBjaCA9ICdfJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX1BFUklPRDogY2ggPSAnPic7IGJyZWFrOwoJCQkJCWNhc2UgU0RMS19TTEFTSDogIGNoID0gJz8nOyBicmVhazsKCgkJCQkJY2FzZSBTRExLXzA6IGNoID0gJyknOyBicmVhazsKCQkJCQljYXNlIFNETEtfMTogY2ggPSAnISc7IGJyZWFrOwoJCQkJCWNhc2UgU0RMS18yOiBjaCA9ICciJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLXzM6IGNoID0gJ6MnOyBicmVhazsKCQkJCQljYXNlIFNETEtfNDogY2ggPSAnJCc7IGJyZWFrOwoJCQkJCWNhc2UgU0RMS181OiBjaCA9ICclJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLXzY6IGNoID0gJ14nOyBicmVhazsKCQkJCQljYXNlIFNETEtfNzogY2ggPSAnJic7IGJyZWFrOwoJCQkJCWNhc2UgU0RMS184OiBjaCA9ICcqJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLXzk6IGNoID0gJygnOyBicmVhazsKCgkJCQkJY2FzZSBTRExLX1NFTUlDT0xPTjogICAgY2ggPSAnOic7IGJyZWFrOwoJCQkJCWNhc2UgU0RMS19FUVVBTFM6ICAgICAgIGNoID0gJysnOyBicmVhazsKCQkJCQljYXNlIFNETEtfTEVGVEJSQUNLRVQ6ICBjaCA9ICd7JzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX0JBQ0tTTEFTSDogICAgY2ggPSAnfCc7IGJyZWFrOwoJCQkJCWNhc2UgU0RMS19SSUdIVEJSQUNLRVQ6IGNoID0gJ30nOyBicmVhazsKCQkJCQljYXNlIFNETEtfQkFDS1FVT1RFOiAgICBjaCA9ICesJzsgYnJlYWs7CgoJCQkJCWRlZmF1bHQ6CgkJCQkJCWNoID0gMDsgLyogTWFwIHRvIHplcm8gY2hhcmFjdGVyIGlmIHdlIGRvbid0IHVuZGVyc3RhbmQgaXQgKi8KCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoKCQkJfSBlbHNlIGlmIChjaCA+IDEyNikKCQkJewoJCQkJLyogU0RMIGtleSBjb2RlIDwgMTI2IG1hcCBkaXJlY3RseSBvbnRvIHRoZWlyIFVuaWNvZGUgZXF1aXZhbGVudHMgKi8KCQkJCS8qIEtleXBhZCAwIHRvIDkgbWFwcyB0byBudW1lcmljIGVxdWl2YWxlbnQgKi8KCQkJCWlmIChjaCA+PSBTRExLX0tQMCAmJiBjaCA8PSBTRExLX0tQOSkgY2ggPSBjaCAtIFNETEtfS1AwICsgJzAnOwoJCQkJZWxzZQoJCQkJewoJCQkJCS8qIEZvbGxvd2luZyBzd2l0Y2ggbWFwcyBvdGhlciBrZXlzIHRoYXQgcHJvZHVjZSBhbiBBc2NpaSB2YWx1ZSAqLwoJCQkJCXN3aXRjaChjaCkKCQkJCQl7CgkJCQkJY2FzZSBTRExLX0tQX1BFUklPRDogICBjaCA9ICcuJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX0tQX0RJVklERTogICBjaCA9ICcvJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX0tQX01VTFRJUExZOiBjaCA9ICcqJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX0tQX01JTlVTOiAgICBjaCA9ICctJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX0tQX1BMVVM6ICAgICBjaCA9ICcrJzsgYnJlYWs7CgkJCQkJY2FzZSBTRExLX0tQX0VRVUFMUzogICBjaCA9ICc9JzsgYnJlYWs7CgoJCQkJCWRlZmF1bHQ6CgkJCQkJCS8qIElmIHdlIGRvbid0IGtub3cgd2hhdCBpdCBpcyBzZXQgdGhlIFVuaWNvZGUgdG8gMCAqLwoJCQkJCQljaCA9IDA7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJfQkJCQoJCX0KCQkJCQoJCWtleXN5bS0+dW5pY29kZSA9IGNoOwoJfQoJcmV0dXJuKGtleXN5bSk7Cn0KCi8qIGVuZCBvZiBTRExfcmlzY29zZXZlbnRzLmMgLi4uICovCgo=