LyoKICogRE9TIGludGVycnVwdCAxNmggaGFuZGxlcgogKgogKiBDb3B5cmlnaHQgMTk5OCBKb3NlcGggUHJhbmV2aWNoCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgoKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJ3aW5jb24uaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChpbnQpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERPU1ZNX0ludDE2SGFuZGxlcgogKgogKiBIYW5kbGVyIGZvciBpbnQgMTZoIChrZXlib2FyZCkKICoKICogTk9URToKICogCiAqICAgIEtFWUIuQ09NIChET1MgPjMuMikgYWRkcyBmdW5jdGlvbnMgdG8gdGhpcyBpbnRlcnJ1cHQsIHRoZXkgYXJlCiAqICAgIG5vdCBjdXJyZW50bHkgbGlzdGVkIGhlcmUuCiAqLwoKdm9pZCBXSU5BUEkgRE9TVk1fSW50MTZIYW5kbGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgIHN3aXRjaCBBSF9yZWcoY29udGV4dCkgewoKICAgY2FzZSAweDAwOiAvKiBHZXQgS2V5c3Ryb2tlICovCiAgICAgIC8qIFJldHVybnM6IEFIID0gU2NhbiBjb2RlCiAgICAgICAgICAgICAgICAgIEFMID0gQVNDSUkgY2hhcmFjdGVyICovCiAgICAgIFRSQUNFKCJHZXQgS2V5c3Ryb2tlXG4iKTsKICAgICAgRE9TVk1fSW50MTZSZWFkQ2hhcigmQUxfcmVnKGNvbnRleHQpLCAmQUhfcmVnKGNvbnRleHQpLCBGQUxTRSk7CiAgICAgIGJyZWFrOwoKICAgY2FzZSAweDAxOiAvKiBDaGVjayBmb3IgS2V5c3Ryb2tlICovCiAgICAgIC8qIFJldHVybnM6IFpGIHNldCBpZiBubyBrZXlzdHJva2UgKi8KICAgICAgLyogICAgICAgICAgQUggPSBTY2FuIGNvZGUgKi8KICAgICAgLyogICAgICAgICAgQUwgPSBBU0NJSSBjaGFyYWN0ZXIgKi8KICAgICAgVFJBQ0UoIkNoZWNrIGZvciBLZXlzdHJva2VcbiIpOwogICAgICBpZiAoIURPU1ZNX0ludDE2UmVhZENoYXIoJkFMX3JlZyhjb250ZXh0KSwgJkFIX3JlZyhjb250ZXh0KSwgVFJVRSkpCiAgICAgIHsKICAgICAgICAgIFNFVF9aRkxBRyhjb250ZXh0KTsKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAgIFJFU0VUX1pGTEFHKGNvbnRleHQpOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgY2FzZSAweDAyOiAvKiBHZXQgU2hpZnQgRmxhZ3MgKi8KICAgICAgQUxfcmVnKGNvbnRleHQpID0gMDsKCiAgICAgIGlmIChHZXRBc3luY0tleVN0YXRlKFZLX1JTSElGVCkpCiAgICAgICAgICBBTF9yZWcoY29udGV4dCkgfD0gMHgwMTsKICAgICAgaWYgKEdldEFzeW5jS2V5U3RhdGUoVktfTFNISUZUKSkKICAgICAgICAgIEFMX3JlZyhjb250ZXh0KSB8PSAweDAyOwogICAgICBpZiAoR2V0QXN5bmNLZXlTdGF0ZShWS19MQ09OVFJPTCkgfHwgR2V0QXN5bmNLZXlTdGF0ZShWS19SQ09OVFJPTCkpCiAgICAgICAgICBBTF9yZWcoY29udGV4dCkgfD0gMHgwNDsKICAgICAgaWYgKEdldEFzeW5jS2V5U3RhdGUoVktfTE1FTlUpIHx8IEdldEFzeW5jS2V5U3RhdGUoVktfUk1FTlUpKQogICAgICAgICAgQUxfcmVnKGNvbnRleHQpIHw9IDB4MDg7CiAgICAgIGlmIChHZXRBc3luY0tleVN0YXRlKFZLX1NDUk9MTCkpCiAgICAgICAgICBBTF9yZWcoY29udGV4dCkgfD0gMHgxMDsKICAgICAgaWYgKEdldEFzeW5jS2V5U3RhdGUoVktfTlVNTE9DSykpCiAgICAgICAgICBBTF9yZWcoY29udGV4dCkgfD0gMHgyMDsKICAgICAgaWYgKEdldEFzeW5jS2V5U3RhdGUoVktfQ0FQSVRBTCkpCiAgICAgICAgICBBTF9yZWcoY29udGV4dCkgfD0gMHg0MDsKICAgICAgaWYgKEdldEFzeW5jS2V5U3RhdGUoVktfSU5TRVJUKSkKICAgICAgICAgIEFMX3JlZyhjb250ZXh0KSB8PSAweDgwOwogICAgICBUUkFDRSgiR2V0IFNoaWZ0IEZsYWdzOiByZXR1cm5pbmcgMHglMDJ4XG4iLCBBTF9yZWcoY29udGV4dCkpOwogICAgICBicmVhazsKCiAgIGNhc2UgMHgwMzogLyogU2V0IFR5cGVtYXRpYyBSYXRlIGFuZCBEZWxheSAqLwogICAgICBGSVhNRSgiU2V0IFR5cGVtYXRpYyBSYXRlIGFuZCBEZWxheSAtIE5vdCBTdXBwb3J0ZWRcbiIpOwogICAgICBicmVhazsKCiAgIGNhc2UgMHgwOTogLyogR2V0IEtleWJvYXJkIEZ1bmN0aW9uYWxpdHkgKi8KICAgICAgRklYTUUoIkdldCBLZXlib2FyZCBGdW5jdGlvbmFsaXR5IC0gTm90IFN1cHBvcnRlZFxuIik7CiAgICAgIC8qIEFzIGEgdGVtcG9yYXJ5IG1lYXN1cmUsIHNheSB0aGF0ICJub3RoaW5nIiBpcyBzdXBwb3J0ZWQuLi4gKi8KICAgICAgQUxfcmVnKGNvbnRleHQpID0gMDsKICAgICAgYnJlYWs7CgogICBjYXNlIDB4MGE6IC8qIEdldCBLZXlib2FyZCBJRCAqLwogICAgICBGSVhNRSgiR2V0IEtleWJvYXJkIElEIC0gTm90IFN1cHBvcnRlZFxuIik7CiAgICAgIGJyZWFrOwoKICAgY2FzZSAweDEwOiAvKiBHZXQgRW5oYW5jZWQgS2V5c3Ryb2tlICovCiAgICAgIFRSQUNFKCJHZXQgRW5oYW5jZWQgS2V5c3Ryb2tlIC0gUGFydGlhbGx5IHN1cHBvcnRlZFxuIik7CiAgICAgIC8qIFJldHVybnM6IEFIID0gU2NhbiBjb2RlCiAgICAgICAgICAgICAgICAgIEFMID0gQVNDSUkgY2hhcmFjdGVyICovCiAgICAgIERPU1ZNX0ludDE2UmVhZENoYXIoJkFMX3JlZyhjb250ZXh0KSwgJkFIX3JlZyhjb250ZXh0KSwgRkFMU0UpOwogICAgICBicmVhazsKCgogICBjYXNlIDB4MTE6IC8qIENoZWNrIGZvciBFbmhhbmNlZCBLZXlzdHJva2UgKi8KICAgICAgLyogUmV0dXJuczogWkYgc2V0IGlmIG5vIGtleXN0cm9rZSAqLwogICAgICAvKiAgICAgICAgICBBSCA9IFNjYW4gY29kZSAqLwogICAgICAvKiAgICAgICAgICBBTCA9IEFTQ0lJIGNoYXJhY3RlciAqLwogICAgICBUUkFDRSgiQ2hlY2sgZm9yIEVuaGFuY2VkIEtleXN0cm9rZSAtIFBhcnRpYWxseSBzdXBwb3J0ZWRcbiIpOwogICAgICBpZiAoIURPU1ZNX0ludDE2UmVhZENoYXIoJkFMX3JlZyhjb250ZXh0KSwgJkFIX3JlZyhjb250ZXh0KSwgVFJVRSkpCiAgICAgIHsKICAgICAgICAgIFNFVF9aRkxBRyhjb250ZXh0KTsKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAgIFJFU0VUX1pGTEFHKGNvbnRleHQpOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgY2FzZSAweDEyOiAvKiBHZXQgRXh0ZW5kZWQgU2hpZnQgU3RhdGVzICovCiAgICAgIEZJWE1FKCJHZXQgRXh0ZW5kZWQgU2hpZnQgU3RhdGVzIC0gTm90IFN1cHBvcnRlZFxuIik7CiAgICAgIGJyZWFrOwoKICAgZGVmYXVsdDoKICAgICAgRklYTUUoIlVua25vd24gSU5UIDE2IGZ1bmN0aW9uIC0gMHgleFxuIiwgQUhfcmVnKGNvbnRleHQpKTsKICAgICAgYnJlYWs7CgogICB9Cn0KCmludCBXSU5BUEkgRE9TVk1fSW50MTZSZWFkQ2hhcihCWVRFKmFzY2lpLEJZVEUqc2NhbixCT09MIHBlZWspCnsKICBCSU9TREFUQSAqZGF0YSA9IERPU01FTV9CaW9zRGF0YSgpOwogIFdPUkQgQ3VyT2ZzID0gZGF0YS0+TmV4dEtiZENoYXJQdHI7CgogIC8qIGNoZWNrIGlmIHRoZXJlJ3MgZGF0YSBpbiBidWZmZXIgKi8KICBpZiAocGVlaykgewogICAgaWYgKEN1ck9mcyA9PSBkYXRhLT5GaXJzdEtiZENoYXJQdHIpCiAgICAgIHJldHVybiAwOwogIH0gZWxzZSB7CiAgICB3aGlsZSAoQ3VyT2ZzID09IGRhdGEtPkZpcnN0S2JkQ2hhclB0cikgewogICAgICAvKiBubyBpbnB1dCBhdmFpbGFibGUgeWV0LCBzbyB3YWl0Li4uICovCiAgICAgIERPU1ZNX1dhaXQoIC0xLCAwICk7CiAgICB9CiAgfQogIC8qIHJlYWQgZnJvbSBrZXlib2FyZCBxdWV1ZSAqLwogIFRSQUNFKCIoJXAsJXAsJWQpIC0+ICUwMnggJTAyeFxuIixhc2NpaSxzY2FuLHBlZWssKChCWVRFKilkYXRhKVtDdXJPZnNdLCgoQllURSopZGF0YSlbQ3VyT2ZzKzFdKTsKICBpZiAoYXNjaWkpICphc2NpaSA9ICgoQllURSopZGF0YSlbQ3VyT2ZzXTsKICBpZiAoc2NhbikgKnNjYW4gPSAoKEJZVEUqKWRhdGEpW0N1ck9mcysxXTsKICBpZiAoIXBlZWspIHsKICAgIEN1ck9mcyArPSAyOwogICAgaWYgKEN1ck9mcyA+PSBkYXRhLT5LYmRCdWZmZXJFbmQpIEN1ck9mcyA9IGRhdGEtPktiZEJ1ZmZlclN0YXJ0OwogICAgZGF0YS0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CiAgfQogIHJldHVybiAxOwp9CgppbnQgV0lOQVBJIERPU1ZNX0ludDE2QWRkQ2hhcihCWVRFIGFzY2lpLEJZVEUgc2NhbikKewogIEJJT1NEQVRBICpkYXRhID0gRE9TTUVNX0Jpb3NEYXRhKCk7CiAgV09SRCBDdXJPZnMgPSBkYXRhLT5GaXJzdEtiZENoYXJQdHI7CiAgV09SRCBOZXh0T2ZzID0gQ3VyT2ZzICsgMjsKCiAgVFJBQ0UoIiglMDJ4LCUwMngpXG4iLGFzY2lpLHNjYW4pOwogIGlmIChOZXh0T2ZzID49IGRhdGEtPktiZEJ1ZmZlckVuZCkgTmV4dE9mcyA9IGRhdGEtPktiZEJ1ZmZlclN0YXJ0OwogIC8qIGNoZWNrIGlmIGJ1ZmZlciBpcyBmdWxsICovCiAgaWYgKE5leHRPZnMgPT0gZGF0YS0+TmV4dEtiZENoYXJQdHIpIHJldHVybiAwOwoKICAvKiBva2F5LCBpbnNlcnQgY2hhcmFjdGVyIGluIHJpbmcgYnVmZmVyICovCiAgKChCWVRFKilkYXRhKVtDdXJPZnNdID0gYXNjaWk7CiAgKChCWVRFKilkYXRhKVtDdXJPZnMrMV0gPSBzY2FuOwoKICBkYXRhLT5GaXJzdEtiZENoYXJQdHIgPSBOZXh0T2ZzOwogIHJldHVybiAxOwp9Cg==