LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKgogKiBrZXl0b29scy5jCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmIEhBVkVfV0lOU09DS19ICiNpbmNsdWRlIDx3aW5zb2NrLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZmRlZiBIQVZFX1NURExJQl9ICiNpbmNsdWRlIDxzdGRsaWIuaD4KI2VuZGlmCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9ETUFMTE9DX0gKI2luY2x1ZGUgPGRtYWxsb2MuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvdHlwZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL291dHB1dF9hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL3V0aWxpdGllcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9hcGkuaD4KI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKIwlpbmNsdWRlIDxvcGVuc3NsL2htYWMuaD4KI2Vsc2UKI2lmZGVmIE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENQojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9tZDUuaD4KI2VuZGlmCiNlbmRpZgoKI2lmZGVmIE5FVFNOTVBfVVNFX1BLQ1MxMQojaW5jbHVkZSA8c2VjdXJpdHkvY3J5cHRva2kuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zY2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9rZXl0b29scy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvdHJhbnNmb3JtX29pZHMuaD4KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGdlbmVyYXRlX0t1CiAqCiAqIFBhcmFtZXRlcnM6CiAqCSpoYXNodHlwZQlNSUIgT0lEIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUgZm9yIGhhc2hpbmcuCiAqCSBoYXNodHlwZV9sZW4JTGVuZ3RoIG9mIE9JRCB2YWx1ZS4KICoJKlAJCVByZS1hbGxvY2F0ZWQgYnl0ZXMgb2YgcGFzc3BoYXJhc2UuCiAqCSBwcGxlbgkJTGVuZ3RoIG9mIHBhc3NwaHJhc2UuCiAqCSpLdQkJQnVmZmVyIHRvIGNvbnRhaW4gS3UuCiAqCSprdWxlbgkJTGVuZ3RoIG9mIEt1IGJ1ZmZlci4KICogICAgICAKICogUmV0dXJuczoKICoJU05NUEVSUl9TVUNDRVNTCQkJU3VjY2Vzcy4KICoJU05NUEVSUl9HRU5FUlIJCQlBbGwgZXJyb3JzLgogKgogKgogKiBDb252ZXJ0IGEgcGFzc3BocmFzZSBpbnRvIGEgbWFzdGVyIHVzZXIga2V5LCBLdSwgYWNjb3JkaW5nIHRvIHRoZQogKiBhbGdvcml0aG0gZ2l2ZW4gaW4gUkZDIDIyNzQgY29uY2VybmluZyB0aGUgU05NUHYzIFVzZXIgU2VjdXJpdHkgTW9kZWwgKFVTTSkKICogYXMgZm9sbG93czoKICoKICogRXhwYW5kIHRoZSBwYXNzcGhyYXNlIHRvIGZpbGwgdGhlIHBhc3NwaHJhc2UgYnVmZmVyIHNwYWNlLCBpZiBuZWNlc3NhcnksCiAqIGNvbmNhdGVuYXRpb24gYXMgbWFueSBkdXBsaWNhdGVzIGFzIHBvc3NpYmxlIG9mIFAgdG8gaXRzZWxmLiAgSWYgUCBpcwogKiBsYXJnZXIgdGhhbiB0aGUgYnVmZmVyIHNwYWNlLCB0cnVuY2F0ZSBpdCB0byBmaXQuCiAqCiAqIFRoZW4gaGFzaCB0aGUgcmVzdWx0IHdpdGggdGhlIGdpdmVuIGhhc2h0eXBlIHRyYW5zZm9ybS4gIFJldHVybgogKiB0aGUgcmVzdWx0IGFzIEt1LgogKgogKiBJZiBzdWNjZXNzZnVsLCBrdWxlbiBjb250YWlucyB0aGUgc2l6ZSBvZiB0aGUgaGFzaCB3cml0dGVuIHRvIEt1LgogKgogKiBOT1RFICBQYXNzcGhyYXNlcyBsZXNzIHRoYW4gVVNNX0xFTkdUSF9QX01JTiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogKgkgY2F1c2UgYW4gZXJyb3IgdG8gYmUgcmV0dXJuZWQuCiAqCSAoUHVudCB0aGlzIGNoZWNrIHRvIHRoZSBjbWRsaW5lIGFwcHM/ICBYWFgpCiAqLwppbnQKZ2VuZXJhdGVfS3UoY29uc3Qgb2lkICogaGFzaHR5cGUsIHVfaW50IGhhc2h0eXBlX2xlbiwKICAgICAgICAgICAgdV9jaGFyICogUCwgc2l6ZV90IHBwbGVuLCB1X2NoYXIgKiBLdSwgc2l6ZV90ICoga3VsZW4pCiNpZiBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKQp7CiAgICBpbnQgICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfU1VDQ0VTUywKICAgICAgICBuYnl0ZXMgPSBVU01fTEVOR1RIX0VYUEFOREVEX1BBU1NQSFJBU0U7CgogICAgdV9pbnQgICAgICAgICAgIGksIHBpbmRleCA9IDA7CgogICAgdV9jaGFyICAgICAgICAgIGJ1ZltVU01fTEVOR1RIX0tVX0hBU0hCTE9DS10sICpidWZwOwoKI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKICAgIEVWUF9NRF9DVFggICAgICpjdHggPSBOVUxMOwogICAgdW5zaWduZWQgaW50ICAgIHRtcF9sZW47CiNlbHNlCiAgICBNRHN0cnVjdCAgICAgICAgTUQ7CiNlbmRpZgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFoYXNodHlwZSB8fCAhUCB8fCAhS3UgfHwgIWt1bGVuIHx8ICgqa3VsZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9LdV9xdWl0KTsKICAgIH0KCiAgICBpZiAocHBsZW4gPCBVU01fTEVOR1RIX1BfTUlOKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkVycm9yOiBwYXNzcGhyYXNlIGNob3NlbiBpcyBiZWxvdyB0aGUgbGVuZ3RoICIKICAgICAgICAgICAgICAgICAicmVxdWlyZW1lbnRzIG9mIHRoZSBVU00gKG1pbj0lZCkuXG4iLFVTTV9MRU5HVEhfUF9NSU4pOwogICAgICAgIHNubXBfc2V0X2RldGFpbCgiVGhlIHN1cHBsaWVkIHBhc3N3b3JkIGxlbmd0aCBpcyB0b28gc2hvcnQuIik7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiAgICB9CgoKICAgIC8qCiAgICAgKiBTZXR1cCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlLgogICAgICovCiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCgojaWZkZWYgSEFWRV9FVlBfTURfQ1RYX0NSRUFURQogICAgY3R4ID0gRVZQX01EX0NUWF9jcmVhdGUoKTsKI2Vsc2UKICAgIGN0eCA9IG1hbGxvYyhzaXplb2YoKmN0eCkpOwogICAgaWYgKCFFVlBfTURfQ1RYX2luaXQoY3R4KSkKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiNlbmRpZgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ01ENUF1dGgpKSB7CiAgICAgICAgaWYgKCFFVlBfRGlnZXN0SW5pdChjdHgsIEVWUF9tZDUoKSkpCiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0gZWxzZQojZW5kaWYKICAgICAgICBpZiAoSVNUUkFOU0ZPUk0oaGFzaHR5cGUsIEhNQUNTSEExQXV0aCkpIHsKICAgICAgICAgICAgaWYgKCFFVlBfRGlnZXN0SW5pdChjdHgsIEVWUF9zaGExKCkpKQogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0gZWxzZQogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX0t1X3F1aXQpOwojZWxzZQogICAgTURiZWdpbigmTUQpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfVVNFX09QRU5TU0wgKi8KCiAgICB3aGlsZSAobmJ5dGVzID4gMCkgewogICAgICAgIGJ1ZnAgPSBidWY7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLOyBpKyspIHsKICAgICAgICAgICAgKmJ1ZnArKyA9IFBbcGluZGV4KysgJSBwcGxlbl07CiAgICAgICAgfQojaWZkZWYgTkVUU05NUF9VU0VfT1BFTlNTTAogICAgICAgIEVWUF9EaWdlc3RVcGRhdGUoY3R4LCBidWYsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLKTsKI2VsaWYgTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1CiAgICAgICAgaWYgKE1EdXBkYXRlKCZNRCwgYnVmLCBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSyAqIDgpKSB7CiAgICAgICAgICAgIHJ2YWwgPSBTTk1QRVJSX1VTTV9FTkNSWVBUSU9ORVJST1I7CiAgICAgICAgICAgIGdvdG8gbWQ1X2ZpbjsKICAgICAgICB9CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfT1BFTlNTTCAqLwoKICAgICAgICBuYnl0ZXMgLT0gVVNNX0xFTkdUSF9LVV9IQVNIQkxPQ0s7CiAgICB9CgojaWZkZWYgTkVUU05NUF9VU0VfT1BFTlNTTAogICAgdG1wX2xlbiA9ICprdWxlbjsKICAgIEVWUF9EaWdlc3RGaW5hbChjdHgsICh1bnNpZ25lZCBjaGFyICopIEt1LCAmdG1wX2xlbik7CiAgICAqa3VsZW4gPSB0bXBfbGVuOwogICAgLyoKICAgICAqIHdoYXQgYWJvdXQgZnJlZSgpIAogICAgICovCiNlbGlmIE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENQogICAgaWYgKE1EdXBkYXRlKCZNRCwgYnVmLCAwKSkgewogICAgICAgIHJ2YWwgPSBTTk1QRVJSX1VTTV9FTkNSWVBUSU9ORVJST1I7CiAgICAgICAgZ290byBtZDVfZmluOwogICAgfQogICAgKmt1bGVuID0gc2NfZ2V0X3Byb3Blcmxlbmd0aChoYXNodHlwZSwgaGFzaHR5cGVfbGVuKTsKICAgIE1EZ2V0KCZNRCwgS3UsICprdWxlbik7CiAgbWQ1X2ZpbjoKICAgIG1lbXNldCgmTUQsIDAsIHNpemVvZihNRCkpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSAqLwoKCiNpZmRlZiBORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUKICAgIERFQlVHTVNHVEwoKCJnZW5lcmF0ZV9LdSIsICJnZW5lcmF0aW5nIEt1IChmcm9tICVzKTogIiwgUCkpOwogICAgZm9yIChpID0gMDsgaSA8ICprdWxlbjsgaSsrKQogICAgICAgIERFQlVHTVNHKCgiZ2VuZXJhdGVfS3UiLCAiJTAyeCIsIEt1W2ldKSk7CiAgICBERUJVR01TRygoImdlbmVyYXRlX0t1IiwgIlxuIikpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERSAqLwoKCiAgZ2VuZXJhdGVfS3VfcXVpdDoKICAgIG1lbXNldChidWYsIDAsIHNpemVvZihidWYpKTsKI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKICAgIGlmIChjdHgpIHsKI2lmZGVmIEhBVkVfRVZQX01EX0NUWF9ERVNUUk9ZCiAgICAgICAgRVZQX01EX0NUWF9kZXN0cm95KGN0eCk7CiNlbHNlCiAgICAgICAgRVZQX01EX0NUWF9jbGVhbnVwKGN0eCk7CiAgICAgICAgZnJlZShjdHgpOwojZW5kaWYKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gcnZhbDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGdlbmVyYXRlX0t1KCkgKi8KI2VsaWYgTkVUU05NUF9VU0VfUEtDUzExCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTOwoKICAgIC8qCiAgICAgKiBTYW5pdHkgY2hlY2suCiAgICAgKi8KICAgIGlmICghaGFzaHR5cGUgfHwgIVAgfHwgIUt1IHx8ICFrdWxlbiB8fCAoKmt1bGVuIDw9IDApCiAgICAgICAgfHwgKGhhc2h0eXBlX2xlbiAhPSBVU01fTEVOR1RIX09JRF9UUkFOU0ZPUk0pKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiAgICB9CgogICAgaWYgKHBwbGVuIDwgVVNNX0xFTkdUSF9QX01JTikgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJFcnJvcjogcGFzc3BocmFzZSBjaG9zZW4gaXMgYmVsb3cgdGhlIGxlbmd0aCAiCiAgICAgICAgICAgICAgICAgInJlcXVpcmVtZW50cyBvZiB0aGUgVVNNIChtaW49JWQpLlxuIixVU01fTEVOR1RIX1BfTUlOKTsKICAgICAgICBzbm1wX3NldF9kZXRhaWwoIlRoZSBzdXBwbGllZCBwYXNzd29yZCBsZW5ndGggaXMgdG9vIHNob3J0LiIpOwogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX0t1X3F1aXQpOwogICAgfQoKICAgIC8qCiAgICAgKiBTZXR1cCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlLgogICAgICovCgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ01ENUF1dGgpKQogICAgICAgIHJldHVybiBwa2NzX2dlbmVyYXRlX0t1KENLTV9NRDUsIFAsIHBwbGVuLCBLdSwga3VsZW4pOwogICAgZWxzZQojZW5kaWYKICAgICAgICBpZiAoSVNUUkFOU0ZPUk0oaGFzaHR5cGUsIEhNQUNTSEExQXV0aCkpCiAgICAgICAgcmV0dXJuIHBrY3NfZ2VuZXJhdGVfS3UoQ0tNX1NIQV8xLCBQLCBwcGxlbiwgS3UsIGt1bGVuKTsKICAgIGVsc2UgewogICAgICAgIHJldHVybiAoU05NUEVSUl9HRU5FUlIpOwogICAgfQoKICBnZW5lcmF0ZV9LdV9xdWl0OgoKICAgIHJldHVybiBydmFsOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBnZW5lcmF0ZV9LdSgpICovCiNlbHNlCl9LRVlUT09MU19OT1RfQVZBSUxBQkxFCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaW50ZXJuYWwgb3Igb3BlbnNzbCAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBnZW5lcmF0ZV9rdWwKICoKICogUGFyYW1ldGVyczoKICoJKmhhc2h0eXBlCiAqCSBoYXNodHlwZV9sZW4KICoJKmVuZ2luZUlECiAqCSBlbmdpbmVJRF9sZW4KICoJKkt1CQlNYXN0ZXIga2V5IGZvciBhIGdpdmVuIHVzZXIuCiAqCSBrdV9sZW4JCUxlbmd0aCBvZiBLdSBpbiBieXRlcy4KICoJKkt1bAkJTG9jYWxpemVkIGtleSBmb3IgYSBnaXZlbiB1c2VyIGF0IGVuZ2luZUlELgogKgkqa3VsX2xlbglMZW5ndGggb2YgS3VsIGJ1ZmZlciAoSU4pOyBMZW5ndGggb2YgS3VsIGtleSAoT1VUKS4KICogICAgICAKICogUmV0dXJuczoKICoJU05NUEVSUl9TVUNDRVNTCQkJU3VjY2Vzcy4KICoJU05NUEVSUl9HRU5FUlIJCQlBbGwgZXJyb3JzLgogKgogKgogKiBLdSBNVVNUIGJlIHRoZSBwcm9wZXIgbGVuZ3RoIChjdXJyZW50bHkgZml4ZWQpIGZvciB0aGUgZ2l2ZW4gaGFzaHR5cGUuCiAqCiAqIFVwb24gc3VjY2Vzc2Z1bCByZXR1cm4sIEt1bCBjb250YWlucyB0aGUgbG9jYWxpemVkIGZvcm0gb2YgS3UgYXQKICogZW5naW5lSUQsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZSBrZXkgaXMgc3RvcmVkIGluIGt1bF9sZW4uCiAqCiAqIFRoZSBsb2NhbGl6ZWQga2V5IG1ldGhvZCBpcyBkZWZpbmVkIGluIFJGQzIyNzQsIFNlY3Rpb25zIDIuNiBhbmQgQS4yLCBhbmQKICogb3JpZ2luYWxseSBkb2N1bWVudGVkIGluOgogKiAgCVUuIEJsdW1lbnRoYWwsIE4uIEMuIEhpZW4sIEIuIFdpam5lbiwKICogICAgIAkiS2V5IERlcml2YXRpb24gZm9yIE5ldHdvcmsgTWFuYWdlbWVudCBBcHBsaWNhdGlvbnMiLAogKglJRUVFIE5ldHdvcmsgTWFnYXppbmUsIEFwcmlsL01heSBpc3N1ZSwgMTk5Ny4KICoKICoKICogQVNTVU1FUyAgU05NUF9NQVhCVUYgPj0gc2l6ZW9mKEt1ICsgZW5naW5lSUQgKyBLdSkuCiAqCiAqIE5PVEUgIExvY2FsaXplZCBrZXlzIGZvciBwcml2YWN5IHRyYW5zZm9ybXMgYXJlIGdlbmVyYXRlZCB2aWEKICoJIHRoZSBhdXRoZW50aWNhdGlvbiB0cmFuc2Zvcm0gaGVsZCBieSB0aGUgc2FtZSB1c21Vc2VyLgogKgogKiBYWFgJQW4gZW5naW5lSUQgb2YgYW55IGxlbmd0aCBpcyBhY2NlcHRlZCwgZXZlbiBpZiBsYXJnZXIgdGhhbgogKgl3aGF0IGlzIHNwZWMnZWQgZm9yIHRoZSB0ZXh0dWFsIGNvbnZlbnRpb24uCiAqLwppbnQKZ2VuZXJhdGVfa3VsKGNvbnN0IG9pZCAqIGhhc2h0eXBlLCB1X2ludCBoYXNodHlwZV9sZW4sCiAgICAgICAgICAgICB1X2NoYXIgKiBlbmdpbmVJRCwgc2l6ZV90IGVuZ2luZUlEX2xlbiwKICAgICAgICAgICAgIHVfY2hhciAqIEt1LCBzaXplX3Qga3VfbGVuLAogICAgICAgICAgICAgdV9jaGFyICogS3VsLCBzaXplX3QgKiBrdWxfbGVuKQojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9QS0NTMTEpCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTOwogICAgdV9pbnQgICAgICAgICAgIG5ieXRlcyA9IDA7CiAgICBzaXplX3QgICAgICAgICAgcHJvcGVybGVuZ3RoOwogICAgaW50ICAgICAgICAgICAgIGlwcm9wZXJsZW5ndGg7CgogICAgdV9jaGFyICAgICAgICAgIGJ1ZltTTk1QX01BWEJVRl07CiNpZmRlZiBORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUKICAgIGludCAgICAgICAgICAgICBpOwojZW5kaWYKCgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFoYXNodHlwZSB8fCAhZW5naW5lSUQgfHwgIUt1IHx8ICFLdWwgfHwgIWt1bF9sZW4KICAgICAgICB8fCAoZW5naW5lSURfbGVuIDw9IDApIHx8IChrdV9sZW4gPD0gMCkgfHwgKCprdWxfbGVuIDw9IDApCiAgICAgICAgfHwgKGhhc2h0eXBlX2xlbiAhPSBVU01fTEVOR1RIX09JRF9UUkFOU0ZPUk0pKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfa3VsX3F1aXQpOwogICAgfQoKCiAgICBpcHJvcGVybGVuZ3RoID0gc2NfZ2V0X3Byb3Blcmxlbmd0aChoYXNodHlwZSwgaGFzaHR5cGVfbGVuKTsKICAgIGlmIChpcHJvcGVybGVuZ3RoID09IFNOTVBFUlJfR0VORVJSKQogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX2t1bF9xdWl0KTsKCiAgICBwcm9wZXJsZW5ndGggPSAoc2l6ZV90KSBpcHJvcGVybGVuZ3RoOwoKICAgIGlmICgoKGludCkgKmt1bF9sZW4gPCBwcm9wZXJsZW5ndGgpIHx8ICgoaW50KSBrdV9sZW4gPCBwcm9wZXJsZW5ndGgpKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfa3VsX3F1aXQpOwogICAgfQoKICAgIC8qCiAgICAgKiBDb25jYXRlbmF0ZSBLdSBhbmQgZW5naW5lSUQgcHJvcGVybHksIHRoZW4gaGFzaCB0aGUgcmVzdWx0LgogICAgICogU3RvcmUgaXQgaW4gS3VsLgogICAgICovCiAgICBuYnl0ZXMgPSAwOwogICAgbWVtY3B5KGJ1ZiwgS3UsIHByb3Blcmxlbmd0aCk7CiAgICBuYnl0ZXMgKz0gcHJvcGVybGVuZ3RoOwogICAgbWVtY3B5KGJ1ZiArIG5ieXRlcywgZW5naW5lSUQsIGVuZ2luZUlEX2xlbik7CiAgICBuYnl0ZXMgKz0gZW5naW5lSURfbGVuOwogICAgbWVtY3B5KGJ1ZiArIG5ieXRlcywgS3UsIHByb3Blcmxlbmd0aCk7CiAgICBuYnl0ZXMgKz0gcHJvcGVybGVuZ3RoOwoKICAgIHJ2YWwgPSBzY19oYXNoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4sIGJ1ZiwgbmJ5dGVzLCBLdWwsIGt1bF9sZW4pOwoKI2lmZGVmIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERQogICAgREVCVUdNU0dUTCgoImdlbmVyYXRlX2t1bCIsICJnZW5lcmF0aW5nIEt1bCAoZnJvbSBLdSk6ICIpKTsKICAgIGZvciAoaSA9IDA7IGkgPCAqa3VsX2xlbjsgaSsrKQogICAgICAgIERFQlVHTVNHKCgiZ2VuZXJhdGVfa3VsIiwgIiUwMngiLCBLdWxbaV0pKTsKICAgIERFQlVHTVNHKCgiZ2VuZXJhdGVfa3VsIiwgImtleXRvb2xzXG4iKSk7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFICovCgogICAgUVVJVEZVTihydmFsLCBnZW5lcmF0ZV9rdWxfcXVpdCk7CgoKICBnZW5lcmF0ZV9rdWxfcXVpdDoKICAgIHJldHVybiBydmFsOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgZ2VuZXJhdGVfa3VsKCkgKi8KCiNlbHNlCl9LRVlUT09MU19OT1RfQVZBSUxBQkxFCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaW50ZXJuYWwgb3Igb3BlbnNzbCAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBlbmNvZGVfa2V5Y2hhbmdlCiAqCiAqIFBhcmFtZXRlcnM6CiAqCSpoYXNodHlwZQlNSUIgT0lEIGZvciB0aGUgaGFzaCB0cmFuc2Zvcm0gdHlwZS4KICoJIGhhc2h0eXBlX2xlbglMZW5ndGggb2YgdGhlIE1JQiBPSUQgaGFzaCB0cmFuc2Zvcm0gdHlwZS4KICoJKm9sZGtleQkJT2xkIGtleSB0aGF0IGlzIHVzZWQgdG8gZW5jb2RlcyB0aGUgbmV3IGtleS4KICoJIG9sZGtleV9sZW4JTGVuZ3RoIG9mIG9sZGtleSBpbiBieXRlcy4KICoJKm5ld2tleQkJTmV3IGtleSB0aGF0IGlzIGVuY29kZWQgdXNpbmcgdGhlIG9sZCBrZXkuCiAqCSBuZXdrZXlfbGVuCUxlbmd0aCBvZiBuZXcga2V5IGluIGJ5dGVzLgogKgkqa2NzdHJpbmcJQnVmZmVyIHRvIGNvbnRhaW4gdGhlIEtleUNoYW5nZSBUQyBzdHJpbmcuCiAqCSprY3N0cmluZ19sZW4JTGVuZ3RoIG9mIGtjc3RyaW5nIGJ1ZmZlci4KICogICAgICAKICogUmV0dXJuczoKICoJU05NUEVSUl9TVUNDRVNTCQkJU3VjY2Vzcy4KICoJU05NUEVSUl9HRU5FUlIJCQlBbGwgZXJyb3JzLgogKgogKgogKiBVc2VzIG9sZGtleSBhbmQgYWNxdWlyZWQgcmFuZG9tIGJ5dGVzIHRvIGVuY29kZSBuZXdrZXkgaW50byBrY3N0cmluZwogKiBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIG9mIHRoZSBLZXlDaGFuZ2UgVEMgZGVzY3JpYmVkIGluIFJGQyAyMjc0LCBTZWN0aW9uIDUuCiAqCiAqIFVwb24gc3VjY2Vzc2Z1bCByZXR1cm4sICprY3N0cmluZ19sZW4gY29udGFpbnMgdGhlIGxlbmd0aCBvZiB0aGUKICogZW5jb2RlZCBzdHJpbmcuCiAqCiAqIEFTU1VNRVMJT2xkIGFuZCBuZXcga2V5IGFyZSBhbHdheXMgZXF1YWwgdG8gZWFjaCBvdGhlciwgYWx0aG91Z2gKICoJCXRoaXMgbWF5IGJlIGxlc3MgdGhhbiB0aGUgdHJhbnNmb3JtIHR5cGUgaGFzaCBvdXRwdXQKICogCQlvdXRwdXQgbGVuZ3RoIChlZywgdXNpbmcgS2V5Q2hhbmdlIGZvciBhIERFU1ByaXYga2V5IHdoZW4KICoJCXRoZSB1c2VyIGFsc28gdXNlcyBTSEExQXV0aCkuICBUaGlzIGFsc28gaW1wbGllcyB0aGF0IHRoZQogKgkJaGFzaCBwbGFjZWQgaW4gdGhlIHNlY29uZCAxLzIgb2YgdGhlIGtleSBjaGFuZ2Ugc3RyaW5nCiAqCQl3aWxsIGJlIHRydW5jYXRlZCBiZWZvcmUgdGhlIFhPUidpbmcgd2hlbiB0aGUgaGFzaCBvdXRwdXQgaXMgCiAqCQlsYXJnZXIgdGhhbiB0aGF0IDEvMiBvZiB0aGUga2V5IGNoYW5nZSBzdHJpbmcuCiAqCiAqCQkqa2NzdHJpbmdfbGVuIHdpbGwgYmUgcmV0dXJuZWQgYXMgZXhhY3RseSB0d2ljZSB0aGF0IHNhbWUKICoJCWxlbmd0aCB0aG91Z2ggdGhlIGlucHV0IGJ1ZmZlciBtYXkgYmUgbGFyZ2VyLgogKgogKiBYWFggRklYOiAgICAgRG9lcyBub3QgaGFuZGxlIHZhcmliYWJsZSBsZW5ndGgga2V5cy4KICogWFhYIEZJWDogICAgIERvZXMgbm90IGhhbmRsZSBrZXlzIGxhcmdlciB0aGFuIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLgogKi8KaW50CmVuY29kZV9rZXljaGFuZ2UoY29uc3Qgb2lkICogaGFzaHR5cGUsIHVfaW50IGhhc2h0eXBlX2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBvbGRrZXksIHNpemVfdCBvbGRrZXlfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIG5ld2tleSwgc2l6ZV90IG5ld2tleV9sZW4sCiAgICAgICAgICAgICAgICAgdV9jaGFyICoga2NzdHJpbmcsIHNpemVfdCAqIGtjc3RyaW5nX2xlbikKI2lmIGRlZmluZWQoTkVUU05NUF9VU0VfT1BFTlNTTCkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfUEtDUzExKQp7CiAgICBpbnQgICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgIHNpemVfdCAgICAgICAgICBwcm9wZXJsZW5ndGg7CiAgICBzaXplX3QgICAgICAgICAgbmJ5dGVzID0gMDsKCiAgICB1X2NoYXIgICAgICAgICAqdG1wYnVmID0gTlVMTDsKCgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFrY3N0cmluZyB8fCAha2NzdHJpbmdfbGVuKQoJcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIGlmICghaGFzaHR5cGUgfHwgIW9sZGtleSB8fCAhbmV3a2V5IHx8ICFrY3N0cmluZyB8fCAha2NzdHJpbmdfbGVuCiAgICAgICAgfHwgKG9sZGtleV9sZW4gPD0gMCkgfHwgKG5ld2tleV9sZW4gPD0gMCkgfHwgKCprY3N0cmluZ19sZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQoKICAgIC8qCiAgICAgKiBTZXR1cCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlLgogICAgICovCiAgICBwcm9wZXJsZW5ndGggPSBzY19nZXRfcHJvcGVybGVuZ3RoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4pOwogICAgaWYgKHByb3Blcmxlbmd0aCA9PSBTTk1QRVJSX0dFTkVSUikKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwoKICAgIGlmICgob2xka2V5X2xlbiAhPSBuZXdrZXlfbGVuKSB8fCAoKmtjc3RyaW5nX2xlbiA8ICgyICogb2xka2V5X2xlbikpKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZW5jb2RlX2tleWNoYW5nZV9xdWl0KTsKICAgIH0KCiAgICBwcm9wZXJsZW5ndGggPSBTTk1QX01JTigoaW50KSBvbGRrZXlfbGVuLCBwcm9wZXJsZW5ndGgpOwoKICAgIC8qCiAgICAgKiBVc2UgdGhlIG9sZCBrZXkgYW5kIHNvbWUgcmFuZG9tIGJ5dGVzIHRvIGVuY29kZSB0aGUgbmV3IGtleQogICAgICogaW4gdGhlIEtleUNoYW5nZSBUQyBmb3JtYXQ6CiAgICAgKiAgICAgIC4gR2V0IHJhbmRvbSBieXRlcyAoc3RvcmUgaW4gZmlyc3QgaGFsZiBvZiBrY3N0cmluZyksCiAgICAgKiAgICAgIC4gSGFzaCAob2xka2V5IHwgcmFuZG9tX2J5dGVzKSAoaW50byBzZWNvbmQgaGFsZiBvZiBrY3N0cmluZyksCiAgICAgKiAgICAgIC4gWE9SIGhhc2ggYW5kIG5ld2tleSAoaW50byBzZWNvbmQgaGFsZiBvZiBrY3N0cmluZykuCiAgICAgKgogICAgICogR2V0dGluZyB0aGUgd3JvbmcgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyBpcyBjb25zaWRlcmVkIGFuIGVycm9yLgogICAgICovCiAgICBuYnl0ZXMgPSBwcm9wZXJsZW5ndGg7CgojaWYgZGVmaW5lZChORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUpICYmIGRlZmluZWQoUkFORE9NWkVST1MpCiAgICBtZW1zZXQoa2NzdHJpbmcsIDAsIG5ieXRlcyk7CiAgICBERUJVR01TRygoImVuY29kZV9rZXljaGFuZ2UiLAogICAgICAgICAgICAgICIqKiBVc2luZyBhbGwgemVybyBiaXRzIGZvciBcInJhbmRvbVwiIGRlbHRhIG9mICkiCiAgICAgICAgICAgICAgInRoZSBrZXljaGFuZ2Ugc3RyaW5nISAqKlxuIikpOwojZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICFORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUgKi8KICAgIHJ2YWwgPSBzY19yYW5kb20oa2NzdHJpbmcsICZuYnl0ZXMpOwogICAgUVVJVEZVTihydmFsLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgaWYgKChpbnQpIG5ieXRlcyAhPSBwcm9wZXJsZW5ndGgpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICFORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUgKi8KCiAgICB0bXBidWYgPSAodV9jaGFyICopIG1hbGxvYyhwcm9wZXJsZW5ndGggKiAyKTsKICAgIGlmICh0bXBidWYpIHsKICAgICAgICBtZW1jcHkodG1wYnVmLCBvbGRrZXksIHByb3Blcmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHRtcGJ1ZiArIHByb3Blcmxlbmd0aCwga2NzdHJpbmcsIHByb3Blcmxlbmd0aCk7CgogICAgICAgICprY3N0cmluZ19sZW4gLT0gcHJvcGVybGVuZ3RoOwogICAgICAgIHJ2YWwgPSBzY19oYXNoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4sIHRtcGJ1ZiwgcHJvcGVybGVuZ3RoICogMiwKICAgICAgICAgICAgICAgICAgICAgICBrY3N0cmluZyArIHByb3Blcmxlbmd0aCwga2NzdHJpbmdfbGVuKTsKCiAgICAgICAgUVVJVEZVTihydmFsLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwoKICAgICAgICAqa2NzdHJpbmdfbGVuID0gKHByb3Blcmxlbmd0aCAqIDIpOwoKICAgICAgICBrY3N0cmluZyArPSBwcm9wZXJsZW5ndGg7CiAgICAgICAgbmJ5dGVzID0gMDsKICAgICAgICB3aGlsZSAoKGludCkgKG5ieXRlcysrKSA8IHByb3Blcmxlbmd0aCkgewogICAgICAgICAgICAqa2NzdHJpbmcrKyBePSAqbmV3a2V5Kys7CiAgICAgICAgfQogICAgfQoKICBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQ6CiAgICBpZiAocnZhbCAhPSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgbWVtc2V0KGtjc3RyaW5nLCAwLCAqa2NzdHJpbmdfbGVuKTsKICAgIFNOTVBfRlJFRSh0bXBidWYpOwoKICAgIHJldHVybiBydmFsOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgZW5jb2RlX2tleWNoYW5nZSgpICovCgojZWxzZQpfS0VZVE9PTFNfTk9UX0FWQUlMQUJMRQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGludGVybmFsIG9yIG9wZW5zc2wgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZGVjb2RlX2tleWNoYW5nZQogKgogKiBQYXJhbWV0ZXJzOgogKgkqaGFzaHR5cGUJTUlCIE9JRCBvZiB0aGUgaGFzaCB0cmFuc2Zvcm0gdG8gdXNlLgogKgkgaGFzaHR5cGVfbGVuCUxlbmd0aCBvZiB0aGUgaGFzaCB0cmFuc2Zvcm0gTUlCIE9JRC4KICoJKm9sZGtleQkJT2xkIGtleSB0aGF0IGlzIHVzZWQgdG8gZW5jb2RlIHRoZSBuZXcga2V5LgogKgkgb2xka2V5X2xlbglMZW5ndGggb2Ygb2xka2V5IGluIGJ5dGVzLgogKgkqa2NzdHJpbmcJRW5jb2RlZCBLZXlTdHJpbmcgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIG5ldyBrZXkuCiAqCSBrY3N0cmluZ19sZW4JTGVuZ3RoIG9mIGtjc3RyaW5nIGluIGJ5dGVzLgogKgkqbmV3a2V5CQlCdWZmZXIgdG8gaG9sZCB0aGUgZXh0cmFjdGVkIG5ldyBrZXkuCiAqCSpuZXdrZXlfbGVuCUxlbmd0aCBvZiBuZXdrZXkgaW4gYnl0ZXMuCiAqICAgICAgCiAqIFJldHVybnM6CiAqCVNOTVBFUlJfU1VDQ0VTUwkJCVN1Y2Nlc3MuCiAqCVNOTVBFUlJfR0VORVJSCQkJQWxsIGVycm9ycy4KICoKICoKICogRGVjb2RlcyBhIHN0cmluZyBvZiBiaXRzIGVuY29kZWQgYWNjb3JkaW5nIHRvIHRoZSBLZXlDaGFuZ2UgVEMgZGVzY3JpYmVkCiAqIGluIFJGQyAyMjc0LCBTZWN0aW9uIDUuICBUaGUgbmV3IGtleSBpcyBleHRyYWN0ZWQgZnJvbSAqa2NzdHJpbmcgd2l0aAogKiB0aGUgYWlkIG9mIHRoZSBvbGQga2V5LgogKgogKiBVcG9uIHN1Y2Nlc3NmdWwgcmV0dXJuLCAqbmV3a2V5X2xlbiBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZSBuZXcga2V5LgogKgogKgogKiBBU1NVTUVTCU9sZCBrZXkgaXMgZXhhY3RseSAxLzIgdGhlIGxlbmd0aCBvZiB0aGUgS2V5Q2hhbmdlIGJ1ZmZlciwKICoJCWFsdGhvdWdoIHRoaXMgbGVuZ3RoIG1heSBiZSBsZXNzIHRoYW4gdGhlIGhhc2ggdHJhbnNmb3JtCiAqCQlvdXRwdXQuICBUaHVzIHRoZSBuZXcga2V5IGxlbmd0aCB3aWxsIGJlIGVxdWFsIHRvIHRoZSBvbGQKICoJCWtleSBsZW5ndGguCiAqLwovKgogKiBYWFg6ICBpZiB0aGUgbmV3a2V5IGlzIG5vdCBsb25nIGVub3VnaCwgaXQgc2hvdWxkIGJlIGZyZWVkIGFuZCByZW1hbGxvY2VkIAogKi8KaW50CmRlY29kZV9rZXljaGFuZ2UoY29uc3Qgb2lkICogaGFzaHR5cGUsIHVfaW50IGhhc2h0eXBlX2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBvbGRrZXksIHNpemVfdCBvbGRrZXlfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIGtjc3RyaW5nLCBzaXplX3Qga2NzdHJpbmdfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIG5ld2tleSwgc2l6ZV90ICogbmV3a2V5X2xlbikKI2lmIGRlZmluZWQoTkVUU05NUF9VU0VfT1BFTlNTTCkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfUEtDUzExKQp7CiAgICBpbnQgICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgIHNpemVfdCAgICAgICAgICBwcm9wZXJsZW5ndGggPSAwOwogICAgaW50ICAgICAgICAgICAgIGlwcm9wZXJsZW5ndGggPSAwOwogICAgdV9pbnQgICAgICAgICAgIG5ieXRlcyA9IDA7CgogICAgdV9jaGFyICAgICAgICAgKmJ1ZnAsIHRtcF9idWZbU05NUF9NQVhCVUZdOwogICAgc2l6ZV90ICAgICAgICAgIHRtcF9idWZfbGVuID0gU05NUF9NQVhCVUY7CiAgICB1X2NoYXIgICAgICAgICAqdG1wYnVmID0gTlVMTDsKCgoKICAgIC8qCiAgICAgKiBTYW5pdHkgY2hlY2suCiAgICAgKi8KICAgIGlmICghaGFzaHR5cGUgfHwgIW9sZGtleSB8fCAha2NzdHJpbmcgfHwgIW5ld2tleSB8fCAhbmV3a2V5X2xlbgogICAgICAgIHx8IChvbGRrZXlfbGVuIDw9IDApIHx8IChrY3N0cmluZ19sZW4gPD0gMCkgfHwgKCpuZXdrZXlfbGVuIDw9IDApCiAgICAgICAgfHwgKGhhc2h0eXBlX2xlbiAhPSBVU01fTEVOR1RIX09JRF9UUkFOU0ZPUk0pKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZGVjb2RlX2tleWNoYW5nZV9xdWl0KTsKICAgIH0KCgogICAgLyoKICAgICAqIFNldHVwIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUuCiAgICAgKi8KICAgIGlwcm9wZXJsZW5ndGggPSBzY19nZXRfcHJvcGVybGVuZ3RoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4pOwogICAgaWYgKGlwcm9wZXJsZW5ndGggPT0gU05NUEVSUl9HRU5FUlIpCiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZGVjb2RlX2tleWNoYW5nZV9xdWl0KTsKCiAgICBwcm9wZXJsZW5ndGggPSAoc2l6ZV90KSBpcHJvcGVybGVuZ3RoOwoKICAgIGlmICgoKG9sZGtleV9sZW4gKiAyKSAhPSBrY3N0cmluZ19sZW4pIHx8ICgqbmV3a2V5X2xlbiA8IG9sZGtleV9sZW4pKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZGVjb2RlX2tleWNoYW5nZV9xdWl0KTsKICAgIH0KCiAgICBwcm9wZXJsZW5ndGggPSBvbGRrZXlfbGVuOwogICAgKm5ld2tleV9sZW4gPSBwcm9wZXJsZW5ndGg7CgogICAgLyoKICAgICAqIFVzZSB0aGUgb2xkIGtleSBhbmQgdGhlIGdpdmVuIEtleUNoYW5nZSBUQyBzdHJpbmcgdG8gcmVjb3ZlcgogICAgICogdGhlIG5ldyBrZXk6CiAgICAgKiAgICAgIC4gSGFzaCAob2xka2V5IHwgcmFuZG9tX2J5dGVzKSAoaW50byBuZXdrZXkpLAogICAgICogICAgICAuIFhPUiBoYXNoIGFuZCBlbmNvZGVkIChzZWNvbmQpIGhhbGYgb2Yga2NzdHJpbmcgKGludG8gbmV3a2V5KS4KICAgICAqLwogICAgdG1wYnVmID0gKHVfY2hhciAqKSBtYWxsb2MocHJvcGVybGVuZ3RoICogMik7CiAgICBpZiAodG1wYnVmKSB7CiAgICAgICAgbWVtY3B5KHRtcGJ1Ziwgb2xka2V5LCBwcm9wZXJsZW5ndGgpOwogICAgICAgIG1lbWNweSh0bXBidWYgKyBwcm9wZXJsZW5ndGgsIGtjc3RyaW5nLCBwcm9wZXJsZW5ndGgpOwoKICAgICAgICBydmFsID0gc2NfaGFzaChoYXNodHlwZSwgaGFzaHR5cGVfbGVuLCB0bXBidWYsIHByb3Blcmxlbmd0aCAqIDIsCiAgICAgICAgICAgICAgICAgICAgICAgdG1wX2J1ZiwgJnRtcF9idWZfbGVuKTsKICAgICAgICBRVUlURlVOKHJ2YWwsIGRlY29kZV9rZXljaGFuZ2VfcXVpdCk7CgogICAgICAgIG1lbWNweShuZXdrZXksIHRtcF9idWYsIHByb3Blcmxlbmd0aCk7CiAgICAgICAgYnVmcCA9IGtjc3RyaW5nICsgcHJvcGVybGVuZ3RoOwogICAgICAgIG5ieXRlcyA9IDA7CiAgICAgICAgd2hpbGUgKChpbnQpIChuYnl0ZXMrKykgPCBwcm9wZXJsZW5ndGgpIHsKICAgICAgICAgICAgKm5ld2tleSsrIF49ICpidWZwKys7CiAgICAgICAgfQogICAgfQoKICBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQ6CiAgICBpZiAocnZhbCAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICBpZiAobmV3a2V5KQogICAgICAgICAgICBtZW1zZXQobmV3a2V5LCAwLCBwcm9wZXJsZW5ndGgpOwogICAgfQogICAgbWVtc2V0KHRtcF9idWYsIDAsIFNOTVBfTUFYQlVGKTsKICAgIGlmICh0bXBidWYgIT0gTlVMTCkKICAgICAgICBTTk1QX0ZSRUUodG1wYnVmKTsKCiAgICByZXR1cm4gcnZhbDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGRlY29kZV9rZXljaGFuZ2UoKSAqLwoKI2Vsc2UKX0tFWVRPT0xTX05PVF9BVkFJTEFCTEUKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbnRlcm5hbCBvciBvcGVuc3NsICovCg==