LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKgogKiBrZXl0b29scy5jCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmIEhBVkVfV0lOU09DS19ICiNpbmNsdWRlIDx3aW5zb2NrLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZmRlZiBIQVZFX1NURExJQl9ICiNpbmNsdWRlIDxzdGRsaWIuaD4KI2VuZGlmCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9ETUFMTE9DX0gKI2luY2x1ZGUgPGRtYWxsb2MuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvdHlwZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL291dHB1dF9hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL3V0aWxpdGllcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9hcGkuaD4KI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKIwlpbmNsdWRlIDxvcGVuc3NsL2htYWMuaD4KI2Vsc2UKI2lmZGVmIE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENQojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9tZDUuaD4KI2VuZGlmCiNlbmRpZgoKI2lmZGVmIE5FVFNOTVBfVVNFX1BLQ1MxMQojaW5jbHVkZSA8c2VjdXJpdHkvY3J5cHRva2kuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zY2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9rZXl0b29scy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvdHJhbnNmb3JtX29pZHMuaD4KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGdlbmVyYXRlX0t1CiAqCiAqIFBhcmFtZXRlcnM6CiAqCSpoYXNodHlwZQlNSUIgT0lEIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUgZm9yIGhhc2hpbmcuCiAqCSBoYXNodHlwZV9sZW4JTGVuZ3RoIG9mIE9JRCB2YWx1ZS4KICoJKlAJCVByZS1hbGxvY2F0ZWQgYnl0ZXMgb2YgcGFzc3BoYXJhc2UuCiAqCSBwcGxlbgkJTGVuZ3RoIG9mIHBhc3NwaHJhc2UuCiAqCSpLdQkJQnVmZmVyIHRvIGNvbnRhaW4gS3UuCiAqCSprdWxlbgkJTGVuZ3RoIG9mIEt1IGJ1ZmZlci4KICogICAgICAKICogUmV0dXJuczoKICoJU05NUEVSUl9TVUNDRVNTCQkJU3VjY2Vzcy4KICoJU05NUEVSUl9HRU5FUlIJCQlBbGwgZXJyb3JzLgogKgogKgogKiBDb252ZXJ0IGEgcGFzc3BocmFzZSBpbnRvIGEgbWFzdGVyIHVzZXIga2V5LCBLdSwgYWNjb3JkaW5nIHRvIHRoZQogKiBhbGdvcml0aG0gZ2l2ZW4gaW4gUkZDIDIyNzQgY29uY2VybmluZyB0aGUgU05NUHYzIFVzZXIgU2VjdXJpdHkgTW9kZWwgKFVTTSkKICogYXMgZm9sbG93czoKICoKICogRXhwYW5kIHRoZSBwYXNzcGhyYXNlIHRvIGZpbGwgdGhlIHBhc3NwaHJhc2UgYnVmZmVyIHNwYWNlLCBpZiBuZWNlc3NhcnksCiAqIGNvbmNhdGVuYXRpb24gYXMgbWFueSBkdXBsaWNhdGVzIGFzIHBvc3NpYmxlIG9mIFAgdG8gaXRzZWxmLiAgSWYgUCBpcwogKiBsYXJnZXIgdGhhbiB0aGUgYnVmZmVyIHNwYWNlLCB0cnVuY2F0ZSBpdCB0byBmaXQuCiAqCiAqIFRoZW4gaGFzaCB0aGUgcmVzdWx0IHdpdGggdGhlIGdpdmVuIGhhc2h0eXBlIHRyYW5zZm9ybS4gIFJldHVybgogKiB0aGUgcmVzdWx0IGFzIEt1LgogKgogKiBJZiBzdWNjZXNzZnVsLCBrdWxlbiBjb250YWlucyB0aGUgc2l6ZSBvZiB0aGUgaGFzaCB3cml0dGVuIHRvIEt1LgogKgogKiBOT1RFICBQYXNzcGhyYXNlcyBsZXNzIHRoYW4gVVNNX0xFTkdUSF9QX01JTiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogKgkgY2F1c2UgYW4gZXJyb3IgdG8gYmUgcmV0dXJuZWQuCiAqCSAoUHVudCB0aGlzIGNoZWNrIHRvIHRoZSBjbWRsaW5lIGFwcHM/ICBYWFgpCiAqLwppbnQKZ2VuZXJhdGVfS3UoY29uc3Qgb2lkICogaGFzaHR5cGUsIHVfaW50IGhhc2h0eXBlX2xlbiwKICAgICAgICAgICAgdV9jaGFyICogUCwgc2l6ZV90IHBwbGVuLCB1X2NoYXIgKiBLdSwgc2l6ZV90ICoga3VsZW4pCiNpZiBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKQp7CiAgICBpbnQgICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfU1VDQ0VTUywKICAgICAgICBuYnl0ZXMgPSBVU01fTEVOR1RIX0VYUEFOREVEX1BBU1NQSFJBU0U7CgogICAgdV9pbnQgICAgICAgICAgIGksIHBpbmRleCA9IDA7CgogICAgdV9jaGFyICAgICAgICAgIGJ1ZltVU01fTEVOR1RIX0tVX0hBU0hCTE9DS10sICpidWZwOwoKI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKICAgIEVWUF9NRF9DVFggICAgICpjdHggPSBOVUxMOwogICAgdW5zaWduZWQgaW50ICAgIHRtcF9sZW47CiNlbHNlCiAgICBNRHN0cnVjdCAgICAgICAgTUQ7CiNlbmRpZgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFoYXNodHlwZSB8fCAhUCB8fCAhS3UgfHwgIWt1bGVuIHx8ICgqa3VsZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9LdV9xdWl0KTsKICAgIH0KCiAgICBpZiAocHBsZW4gPCBVU01fTEVOR1RIX1BfTUlOKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkVycm9yOiBwYXNzcGhyYXNlIGNob3NlbiBpcyBiZWxvdyB0aGUgbGVuZ3RoICIKICAgICAgICAgICAgICAgICAicmVxdWlyZW1lbnRzIG9mIHRoZSBVU00gKG1pbj0lZCkuXG4iLFVTTV9MRU5HVEhfUF9NSU4pOwogICAgICAgIHNubXBfc2V0X2RldGFpbCgiVGhlIHN1cHBsaWVkIHBhc3N3b3JkIGxlbmd0aCBpcyB0b28gc2hvcnQuIik7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiAgICB9CgoKICAgIC8qCiAgICAgKiBTZXR1cCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlLgogICAgICovCiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCgojaWZkZWYgSEFWRV9FVlBfTURfQ1RYX0NSRUFURQogICAgY3R4ID0gRVZQX01EX0NUWF9jcmVhdGUoKTsKI2Vsc2UKICAgIGN0eCA9IG1hbGxvYyhzaXplb2YoKmN0eCkpOwogICAgRVZQX01EX0NUWF9pbml0KGN0eCk7CiNlbmRpZgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ01ENUF1dGgpKQogICAgICAgIEVWUF9EaWdlc3RJbml0KGN0eCwgRVZQX21kNSgpKTsKICAgIGVsc2UKI2VuZGlmCiAgICAgICAgaWYgKElTVFJBTlNGT1JNKGhhc2h0eXBlLCBITUFDU0hBMUF1dGgpKQogICAgICAgIEVWUF9EaWdlc3RJbml0KGN0eCwgRVZQX3NoYTEoKSk7CiAgICBlbHNlCiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiNlbHNlCiAgICBNRGJlZ2luKCZNRCk7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfT1BFTlNTTCAqLwoKICAgIHdoaWxlIChuYnl0ZXMgPiAwKSB7CiAgICAgICAgYnVmcCA9IGJ1ZjsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgVVNNX0xFTkdUSF9LVV9IQVNIQkxPQ0s7IGkrKykgewogICAgICAgICAgICAqYnVmcCsrID0gUFtwaW5kZXgrKyAlIHBwbGVuXTsKICAgICAgICB9CiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCiAgICAgICAgRVZQX0RpZ2VzdFVwZGF0ZShjdHgsIGJ1ZiwgVVNNX0xFTkdUSF9LVV9IQVNIQkxPQ0spOwojZWxpZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUKICAgICAgICBpZiAoTUR1cGRhdGUoJk1ELCBidWYsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLICogOCkpIHsKICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfVVNNX0VOQ1JZUFRJT05FUlJPUjsKICAgICAgICAgICAgZ290byBtZDVfZmluOwogICAgICAgIH0KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9PUEVOU1NMICovCgogICAgICAgIG5ieXRlcyAtPSBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSzsKICAgIH0KCiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCiAgICB0bXBfbGVuID0gKmt1bGVuOwogICAgRVZQX0RpZ2VzdEZpbmFsKGN0eCwgKHVuc2lnbmVkIGNoYXIgKikgS3UsICZ0bXBfbGVuKTsKICAgICprdWxlbiA9IHRtcF9sZW47CiAgICAvKgogICAgICogd2hhdCBhYm91dCBmcmVlKCkgCiAgICAgKi8KI2VsaWYgTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1CiAgICBpZiAoTUR1cGRhdGUoJk1ELCBidWYsIDApKSB7CiAgICAgICAgcnZhbCA9IFNOTVBFUlJfVVNNX0VOQ1JZUFRJT05FUlJPUjsKICAgICAgICBnb3RvIG1kNV9maW47CiAgICB9CiAgICAqa3VsZW4gPSBzY19nZXRfcHJvcGVybGVuZ3RoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4pOwogICAgTURnZXQoJk1ELCBLdSwgKmt1bGVuKTsKICBtZDVfZmluOgogICAgbWVtc2V0KCZNRCwgMCwgc2l6ZW9mKE1EKSk7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1ICovCgoKI2lmZGVmIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERQogICAgREVCVUdNU0dUTCgoImdlbmVyYXRlX0t1IiwgImdlbmVyYXRpbmcgS3UgKGZyb20gJXMpOiAiLCBQKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgKmt1bGVuOyBpKyspCiAgICAgICAgREVCVUdNU0coKCJnZW5lcmF0ZV9LdSIsICIlMDJ4IiwgS3VbaV0pKTsKICAgIERFQlVHTVNHKCgiZ2VuZXJhdGVfS3UiLCAiXG4iKSk7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFICovCgoKICBnZW5lcmF0ZV9LdV9xdWl0OgogICAgbWVtc2V0KGJ1ZiwgMCwgc2l6ZW9mKGJ1ZikpOwojaWZkZWYgTkVUU05NUF9VU0VfT1BFTlNTTAogICAgaWYgKGN0eCkgewojaWZkZWYgSEFWRV9FVlBfTURfQ1RYX0RFU1RST1kKICAgICAgICBFVlBfTURfQ1RYX2Rlc3Ryb3koY3R4KTsKI2Vsc2UKICAgICAgICBFVlBfTURfQ1RYX2NsZWFudXAoY3R4KTsKICAgICAgICBmcmVlKGN0eCk7CiNlbmRpZgogICAgfQojZW5kaWYKICAgIHJldHVybiBydmFsOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgZ2VuZXJhdGVfS3UoKSAqLwojZWxpZiBORVRTTk1QX1VTRV9QS0NTMTEKewogICAgaW50ICAgICAgICAgICAgIHJ2YWwgPSBTTk1QRVJSX1NVQ0NFU1M7CgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFoYXNodHlwZSB8fCAhUCB8fCAhS3UgfHwgIWt1bGVuIHx8ICgqa3VsZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9LdV9xdWl0KTsKICAgIH0KCiAgICBpZiAocHBsZW4gPCBVU01fTEVOR1RIX1BfTUlOKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkVycm9yOiBwYXNzcGhyYXNlIGNob3NlbiBpcyBiZWxvdyB0aGUgbGVuZ3RoICIKICAgICAgICAgICAgICAgICAicmVxdWlyZW1lbnRzIG9mIHRoZSBVU00gKG1pbj0lZCkuXG4iLFVTTV9MRU5HVEhfUF9NSU4pOwogICAgICAgIHNubXBfc2V0X2RldGFpbCgiVGhlIHN1cHBsaWVkIHBhc3N3b3JkIGxlbmd0aCBpcyB0b28gc2hvcnQuIik7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiAgICB9CgogICAgLyoKICAgICAqIFNldHVwIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUuCiAgICAgKi8KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01ENQogICAgaWYgKElTVFJBTlNGT1JNKGhhc2h0eXBlLCBITUFDTUQ1QXV0aCkpCiAgICAgICAgcmV0dXJuIHBrY3NfZ2VuZXJhdGVfS3UoQ0tNX01ENSwgUCwgcHBsZW4sIEt1LCBrdWxlbik7CiAgICBlbHNlCiNlbmRpZgogICAgICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ1NIQTFBdXRoKSkKICAgICAgICByZXR1cm4gcGtjc19nZW5lcmF0ZV9LdShDS01fU0hBXzEsIFAsIHBwbGVuLCBLdSwga3VsZW4pOwogICAgZWxzZSB7CiAgICAgICAgcmV0dXJuIChTTk1QRVJSX0dFTkVSUik7CiAgICB9CgogIGdlbmVyYXRlX0t1X3F1aXQ6CgogICAgcmV0dXJuIHJ2YWw7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGdlbmVyYXRlX0t1KCkgKi8KI2Vsc2UKX0tFWVRPT0xTX05PVF9BVkFJTEFCTEUKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbnRlcm5hbCBvciBvcGVuc3NsICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGdlbmVyYXRlX2t1bAogKgogKiBQYXJhbWV0ZXJzOgogKgkqaGFzaHR5cGUKICoJIGhhc2h0eXBlX2xlbgogKgkqZW5naW5lSUQKICoJIGVuZ2luZUlEX2xlbgogKgkqS3UJCU1hc3RlciBrZXkgZm9yIGEgZ2l2ZW4gdXNlci4KICoJIGt1X2xlbgkJTGVuZ3RoIG9mIEt1IGluIGJ5dGVzLgogKgkqS3VsCQlMb2NhbGl6ZWQga2V5IGZvciBhIGdpdmVuIHVzZXIgYXQgZW5naW5lSUQuCiAqCSprdWxfbGVuCUxlbmd0aCBvZiBLdWwgYnVmZmVyIChJTik7IExlbmd0aCBvZiBLdWwga2V5IChPVVQpLgogKiAgICAgIAogKiBSZXR1cm5zOgogKglTTk1QRVJSX1NVQ0NFU1MJCQlTdWNjZXNzLgogKglTTk1QRVJSX0dFTkVSUgkJCUFsbCBlcnJvcnMuCiAqCiAqCiAqIEt1IE1VU1QgYmUgdGhlIHByb3BlciBsZW5ndGggKGN1cnJlbnRseSBmaXhlZCkgZm9yIHRoZSBnaXZlbiBoYXNodHlwZS4KICoKICogVXBvbiBzdWNjZXNzZnVsIHJldHVybiwgS3VsIGNvbnRhaW5zIHRoZSBsb2NhbGl6ZWQgZm9ybSBvZiBLdSBhdAogKiBlbmdpbmVJRCwgYW5kIHRoZSBsZW5ndGggb2YgdGhlIGtleSBpcyBzdG9yZWQgaW4ga3VsX2xlbi4KICoKICogVGhlIGxvY2FsaXplZCBrZXkgbWV0aG9kIGlzIGRlZmluZWQgaW4gUkZDMjI3NCwgU2VjdGlvbnMgMi42IGFuZCBBLjIsIGFuZAogKiBvcmlnaW5hbGx5IGRvY3VtZW50ZWQgaW46CiAqICAJVS4gQmx1bWVudGhhbCwgTi4gQy4gSGllbiwgQi4gV2lqbmVuLAogKiAgICAgCSJLZXkgRGVyaXZhdGlvbiBmb3IgTmV0d29yayBNYW5hZ2VtZW50IEFwcGxpY2F0aW9ucyIsCiAqCUlFRUUgTmV0d29yayBNYWdhemluZSwgQXByaWwvTWF5IGlzc3VlLCAxOTk3LgogKgogKgogKiBBU1NVTUVTICBTTk1QX01BWEJVRiA+PSBzaXplb2YoS3UgKyBlbmdpbmVJRCArIEt1KS4KICoKICogTk9URSAgTG9jYWxpemVkIGtleXMgZm9yIHByaXZhY3kgdHJhbnNmb3JtcyBhcmUgZ2VuZXJhdGVkIHZpYQogKgkgdGhlIGF1dGhlbnRpY2F0aW9uIHRyYW5zZm9ybSBoZWxkIGJ5IHRoZSBzYW1lIHVzbVVzZXIuCiAqCiAqIFhYWAlBbiBlbmdpbmVJRCBvZiBhbnkgbGVuZ3RoIGlzIGFjY2VwdGVkLCBldmVuIGlmIGxhcmdlciB0aGFuCiAqCXdoYXQgaXMgc3BlYydlZCBmb3IgdGhlIHRleHR1YWwgY29udmVudGlvbi4KICovCmludApnZW5lcmF0ZV9rdWwoY29uc3Qgb2lkICogaGFzaHR5cGUsIHVfaW50IGhhc2h0eXBlX2xlbiwKICAgICAgICAgICAgIHVfY2hhciAqIGVuZ2luZUlELCBzaXplX3QgZW5naW5lSURfbGVuLAogICAgICAgICAgICAgdV9jaGFyICogS3UsIHNpemVfdCBrdV9sZW4sCiAgICAgICAgICAgICB1X2NoYXIgKiBLdWwsIHNpemVfdCAqIGt1bF9sZW4pCiNpZiBkZWZpbmVkKE5FVFNOTVBfVVNFX09QRU5TU0wpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1KSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX1BLQ1MxMSkKewogICAgaW50ICAgICAgICAgICAgIHJ2YWwgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICB1X2ludCAgICAgICAgICAgbmJ5dGVzID0gMDsKICAgIHNpemVfdCAgICAgICAgICBwcm9wZXJsZW5ndGg7CiAgICBpbnQgICAgICAgICAgICAgaXByb3Blcmxlbmd0aDsKCiAgICB1X2NoYXIgICAgICAgICAgYnVmW1NOTVBfTUFYQlVGXTsKI2lmZGVmIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERQogICAgaW50ICAgICAgICAgICAgIGk7CiNlbmRpZgoKCiAgICAvKgogICAgICogU2FuaXR5IGNoZWNrLgogICAgICovCiAgICBpZiAoIWhhc2h0eXBlIHx8ICFlbmdpbmVJRCB8fCAhS3UgfHwgIUt1bCB8fCAha3VsX2xlbgogICAgICAgIHx8IChlbmdpbmVJRF9sZW4gPD0gMCkgfHwgKGt1X2xlbiA8PSAwKSB8fCAoKmt1bF9sZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9rdWxfcXVpdCk7CiAgICB9CgoKICAgIGlwcm9wZXJsZW5ndGggPSBzY19nZXRfcHJvcGVybGVuZ3RoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4pOwogICAgaWYgKGlwcm9wZXJsZW5ndGggPT0gU05NUEVSUl9HRU5FUlIpCiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfa3VsX3F1aXQpOwoKICAgIHByb3Blcmxlbmd0aCA9IChzaXplX3QpIGlwcm9wZXJsZW5ndGg7CgogICAgaWYgKCgoaW50KSAqa3VsX2xlbiA8IHByb3Blcmxlbmd0aCkgfHwgKChpbnQpIGt1X2xlbiA8IHByb3Blcmxlbmd0aCkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9rdWxfcXVpdCk7CiAgICB9CgogICAgLyoKICAgICAqIENvbmNhdGVuYXRlIEt1IGFuZCBlbmdpbmVJRCBwcm9wZXJseSwgdGhlbiBoYXNoIHRoZSByZXN1bHQuCiAgICAgKiBTdG9yZSBpdCBpbiBLdWwuCiAgICAgKi8KICAgIG5ieXRlcyA9IDA7CiAgICBtZW1jcHkoYnVmLCBLdSwgcHJvcGVybGVuZ3RoKTsKICAgIG5ieXRlcyArPSBwcm9wZXJsZW5ndGg7CiAgICBtZW1jcHkoYnVmICsgbmJ5dGVzLCBlbmdpbmVJRCwgZW5naW5lSURfbGVuKTsKICAgIG5ieXRlcyArPSBlbmdpbmVJRF9sZW47CiAgICBtZW1jcHkoYnVmICsgbmJ5dGVzLCBLdSwgcHJvcGVybGVuZ3RoKTsKICAgIG5ieXRlcyArPSBwcm9wZXJsZW5ndGg7CgogICAgcnZhbCA9IHNjX2hhc2goaGFzaHR5cGUsIGhhc2h0eXBlX2xlbiwgYnVmLCBuYnl0ZXMsIEt1bCwga3VsX2xlbik7CgojaWZkZWYgTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFCiAgICBERUJVR01TR1RMKCgiZ2VuZXJhdGVfa3VsIiwgImdlbmVyYXRpbmcgS3VsIChmcm9tIEt1KTogIikpOwogICAgZm9yIChpID0gMDsgaSA8ICprdWxfbGVuOyBpKyspCiAgICAgICAgREVCVUdNU0coKCJnZW5lcmF0ZV9rdWwiLCAiJTAyeCIsIEt1bFtpXSkpOwogICAgREVCVUdNU0coKCJnZW5lcmF0ZV9rdWwiLCAia2V5dG9vbHNcbiIpKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUgKi8KCiAgICBRVUlURlVOKHJ2YWwsIGdlbmVyYXRlX2t1bF9xdWl0KTsKCgogIGdlbmVyYXRlX2t1bF9xdWl0OgogICAgcmV0dXJuIHJ2YWw7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBnZW5lcmF0ZV9rdWwoKSAqLwoKI2Vsc2UKX0tFWVRPT0xTX05PVF9BVkFJTEFCTEUKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbnRlcm5hbCBvciBvcGVuc3NsICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGVuY29kZV9rZXljaGFuZ2UKICoKICogUGFyYW1ldGVyczoKICoJKmhhc2h0eXBlCU1JQiBPSUQgZm9yIHRoZSBoYXNoIHRyYW5zZm9ybSB0eXBlLgogKgkgaGFzaHR5cGVfbGVuCUxlbmd0aCBvZiB0aGUgTUlCIE9JRCBoYXNoIHRyYW5zZm9ybSB0eXBlLgogKgkqb2xka2V5CQlPbGQga2V5IHRoYXQgaXMgdXNlZCB0byBlbmNvZGVzIHRoZSBuZXcga2V5LgogKgkgb2xka2V5X2xlbglMZW5ndGggb2Ygb2xka2V5IGluIGJ5dGVzLgogKgkqbmV3a2V5CQlOZXcga2V5IHRoYXQgaXMgZW5jb2RlZCB1c2luZyB0aGUgb2xkIGtleS4KICoJIG5ld2tleV9sZW4JTGVuZ3RoIG9mIG5ldyBrZXkgaW4gYnl0ZXMuCiAqCSprY3N0cmluZwlCdWZmZXIgdG8gY29udGFpbiB0aGUgS2V5Q2hhbmdlIFRDIHN0cmluZy4KICoJKmtjc3RyaW5nX2xlbglMZW5ndGggb2Yga2NzdHJpbmcgYnVmZmVyLgogKiAgICAgIAogKiBSZXR1cm5zOgogKglTTk1QRVJSX1NVQ0NFU1MJCQlTdWNjZXNzLgogKglTTk1QRVJSX0dFTkVSUgkJCUFsbCBlcnJvcnMuCiAqCiAqCiAqIFVzZXMgb2xka2V5IGFuZCBhY3F1aXJlZCByYW5kb20gYnl0ZXMgdG8gZW5jb2RlIG5ld2tleSBpbnRvIGtjc3RyaW5nCiAqIGFjY29yZGluZyB0byB0aGUgcnVsZXMgb2YgdGhlIEtleUNoYW5nZSBUQyBkZXNjcmliZWQgaW4gUkZDIDIyNzQsIFNlY3Rpb24gNS4KICoKICogVXBvbiBzdWNjZXNzZnVsIHJldHVybiwgKmtjc3RyaW5nX2xlbiBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZQogKiBlbmNvZGVkIHN0cmluZy4KICoKICogQVNTVU1FUwlPbGQgYW5kIG5ldyBrZXkgYXJlIGFsd2F5cyBlcXVhbCB0byBlYWNoIG90aGVyLCBhbHRob3VnaAogKgkJdGhpcyBtYXkgYmUgbGVzcyB0aGFuIHRoZSB0cmFuc2Zvcm0gdHlwZSBoYXNoIG91dHB1dAogKiAJCW91dHB1dCBsZW5ndGggKGVnLCB1c2luZyBLZXlDaGFuZ2UgZm9yIGEgREVTUHJpdiBrZXkgd2hlbgogKgkJdGhlIHVzZXIgYWxzbyB1c2VzIFNIQTFBdXRoKS4gIFRoaXMgYWxzbyBpbXBsaWVzIHRoYXQgdGhlCiAqCQloYXNoIHBsYWNlZCBpbiB0aGUgc2Vjb25kIDEvMiBvZiB0aGUga2V5IGNoYW5nZSBzdHJpbmcKICoJCXdpbGwgYmUgdHJ1bmNhdGVkIGJlZm9yZSB0aGUgWE9SJ2luZyB3aGVuIHRoZSBoYXNoIG91dHB1dCBpcyAKICoJCWxhcmdlciB0aGFuIHRoYXQgMS8yIG9mIHRoZSBrZXkgY2hhbmdlIHN0cmluZy4KICoKICoJCSprY3N0cmluZ19sZW4gd2lsbCBiZSByZXR1cm5lZCBhcyBleGFjdGx5IHR3aWNlIHRoYXQgc2FtZQogKgkJbGVuZ3RoIHRob3VnaCB0aGUgaW5wdXQgYnVmZmVyIG1heSBiZSBsYXJnZXIuCiAqCiAqIFhYWCBGSVg6ICAgICBEb2VzIG5vdCBoYW5kbGUgdmFyaWJhYmxlIGxlbmd0aCBrZXlzLgogKiBYWFggRklYOiAgICAgRG9lcyBub3QgaGFuZGxlIGtleXMgbGFyZ2VyIHRoYW4gdGhlIGhhc2ggYWxnb3JpdGhtIHVzZWQuCiAqLwppbnQKZW5jb2RlX2tleWNoYW5nZShjb25zdCBvaWQgKiBoYXNodHlwZSwgdV9pbnQgaGFzaHR5cGVfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIG9sZGtleSwgc2l6ZV90IG9sZGtleV9sZW4sCiAgICAgICAgICAgICAgICAgdV9jaGFyICogbmV3a2V5LCBzaXplX3QgbmV3a2V5X2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBrY3N0cmluZywgc2l6ZV90ICoga2NzdHJpbmdfbGVuKQojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9QS0NTMTEpCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTOwogICAgc2l6ZV90ICAgICAgICAgIHByb3Blcmxlbmd0aDsKICAgIHNpemVfdCAgICAgICAgICBuYnl0ZXMgPSAwOwoKICAgIHVfY2hhciAgICAgICAgICp0bXBidWYgPSBOVUxMOwoKCiAgICAvKgogICAgICogU2FuaXR5IGNoZWNrLgogICAgICovCiAgICBpZiAoIWtjc3RyaW5nIHx8ICFrY3N0cmluZ19sZW4pCglyZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgaWYgKCFoYXNodHlwZSB8fCAhb2xka2V5IHx8ICFuZXdrZXkgfHwgIWtjc3RyaW5nIHx8ICFrY3N0cmluZ19sZW4KICAgICAgICB8fCAob2xka2V5X2xlbiA8PSAwKSB8fCAobmV3a2V5X2xlbiA8PSAwKSB8fCAoKmtjc3RyaW5nX2xlbiA8PSAwKQogICAgICAgIHx8IChoYXNodHlwZV9sZW4gIT0gVVNNX0xFTkdUSF9PSURfVFJBTlNGT1JNKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGVuY29kZV9rZXljaGFuZ2VfcXVpdCk7CiAgICB9CgogICAgLyoKICAgICAqIFNldHVwIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUuCiAgICAgKi8KICAgIHByb3Blcmxlbmd0aCA9IHNjX2dldF9wcm9wZXJsZW5ndGgoaGFzaHR5cGUsIGhhc2h0eXBlX2xlbik7CiAgICBpZiAocHJvcGVybGVuZ3RoID09IFNOTVBFUlJfR0VORVJSKQogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGVuY29kZV9rZXljaGFuZ2VfcXVpdCk7CgogICAgaWYgKChvbGRrZXlfbGVuICE9IG5ld2tleV9sZW4pIHx8ICgqa2NzdHJpbmdfbGVuIDwgKDIgKiBvbGRrZXlfbGVuKSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQoKICAgIHByb3Blcmxlbmd0aCA9IFNOTVBfTUlOKChpbnQpIG9sZGtleV9sZW4sIHByb3Blcmxlbmd0aCk7CgogICAgLyoKICAgICAqIFVzZSB0aGUgb2xkIGtleSBhbmQgc29tZSByYW5kb20gYnl0ZXMgdG8gZW5jb2RlIHRoZSBuZXcga2V5CiAgICAgKiBpbiB0aGUgS2V5Q2hhbmdlIFRDIGZvcm1hdDoKICAgICAqICAgICAgLiBHZXQgcmFuZG9tIGJ5dGVzIChzdG9yZSBpbiBmaXJzdCBoYWxmIG9mIGtjc3RyaW5nKSwKICAgICAqICAgICAgLiBIYXNoIChvbGRrZXkgfCByYW5kb21fYnl0ZXMpIChpbnRvIHNlY29uZCBoYWxmIG9mIGtjc3RyaW5nKSwKICAgICAqICAgICAgLiBYT1IgaGFzaCBhbmQgbmV3a2V5IChpbnRvIHNlY29uZCBoYWxmIG9mIGtjc3RyaW5nKS4KICAgICAqCiAgICAgKiBHZXR0aW5nIHRoZSB3cm9uZyBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIGlzIGNvbnNpZGVyZWQgYW4gZXJyb3IuCiAgICAgKi8KICAgIG5ieXRlcyA9IHByb3Blcmxlbmd0aDsKCiNpZiBkZWZpbmVkKE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERSkgJiYgZGVmaW5lZChSQU5ET01aRVJPUykKICAgIG1lbXNldChrY3N0cmluZywgMCwgbmJ5dGVzKTsKICAgIERFQlVHTVNHKCgiZW5jb2RlX2tleWNoYW5nZSIsCiAgICAgICAgICAgICAgIioqIFVzaW5nIGFsbCB6ZXJvIGJpdHMgZm9yIFwicmFuZG9tXCIgZGVsdGEgb2YgKSIKICAgICAgICAgICAgICAidGhlIGtleWNoYW5nZSBzdHJpbmchICoqXG4iKSk7CiNlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogIU5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERSAqLwogICAgcnZhbCA9IHNjX3JhbmRvbShrY3N0cmluZywgJm5ieXRlcyk7CiAgICBRVUlURlVOKHJ2YWwsIGVuY29kZV9rZXljaGFuZ2VfcXVpdCk7CiAgICBpZiAoKGludCkgbmJ5dGVzICE9IHByb3Blcmxlbmd0aCkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGVuY29kZV9rZXljaGFuZ2VfcXVpdCk7CiAgICB9CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogIU5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERSAqLwoKICAgIHRtcGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jKHByb3Blcmxlbmd0aCAqIDIpOwogICAgaWYgKHRtcGJ1ZikgewogICAgICAgIG1lbWNweSh0bXBidWYsIG9sZGtleSwgcHJvcGVybGVuZ3RoKTsKICAgICAgICBtZW1jcHkodG1wYnVmICsgcHJvcGVybGVuZ3RoLCBrY3N0cmluZywgcHJvcGVybGVuZ3RoKTsKCiAgICAgICAgKmtjc3RyaW5nX2xlbiAtPSBwcm9wZXJsZW5ndGg7CiAgICAgICAgcnZhbCA9IHNjX2hhc2goaGFzaHR5cGUsIGhhc2h0eXBlX2xlbiwgdG1wYnVmLCBwcm9wZXJsZW5ndGggKiAyLAogICAgICAgICAgICAgICAgICAgICAgIGtjc3RyaW5nICsgcHJvcGVybGVuZ3RoLCBrY3N0cmluZ19sZW4pOwoKICAgICAgICBRVUlURlVOKHJ2YWwsIGVuY29kZV9rZXljaGFuZ2VfcXVpdCk7CgogICAgICAgICprY3N0cmluZ19sZW4gPSAocHJvcGVybGVuZ3RoICogMik7CgogICAgICAgIGtjc3RyaW5nICs9IHByb3Blcmxlbmd0aDsKICAgICAgICBuYnl0ZXMgPSAwOwogICAgICAgIHdoaWxlICgoaW50KSAobmJ5dGVzKyspIDwgcHJvcGVybGVuZ3RoKSB7CiAgICAgICAgICAgICprY3N0cmluZysrIF49ICpuZXdrZXkrKzsKICAgICAgICB9CiAgICB9CgogIGVuY29kZV9rZXljaGFuZ2VfcXVpdDoKICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICBtZW1zZXQoa2NzdHJpbmcsIDAsICprY3N0cmluZ19sZW4pOwogICAgU05NUF9GUkVFKHRtcGJ1Zik7CgogICAgcmV0dXJuIHJ2YWw7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBlbmNvZGVfa2V5Y2hhbmdlKCkgKi8KCiNlbHNlCl9LRVlUT09MU19OT1RfQVZBSUxBQkxFCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaW50ZXJuYWwgb3Igb3BlbnNzbCAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBkZWNvZGVfa2V5Y2hhbmdlCiAqCiAqIFBhcmFtZXRlcnM6CiAqCSpoYXNodHlwZQlNSUIgT0lEIG9mIHRoZSBoYXNoIHRyYW5zZm9ybSB0byB1c2UuCiAqCSBoYXNodHlwZV9sZW4JTGVuZ3RoIG9mIHRoZSBoYXNoIHRyYW5zZm9ybSBNSUIgT0lELgogKgkqb2xka2V5CQlPbGQga2V5IHRoYXQgaXMgdXNlZCB0byBlbmNvZGUgdGhlIG5ldyBrZXkuCiAqCSBvbGRrZXlfbGVuCUxlbmd0aCBvZiBvbGRrZXkgaW4gYnl0ZXMuCiAqCSprY3N0cmluZwlFbmNvZGVkIEtleVN0cmluZyBidWZmZXIgY29udGFpbmluZyB0aGUgbmV3IGtleS4KICoJIGtjc3RyaW5nX2xlbglMZW5ndGggb2Yga2NzdHJpbmcgaW4gYnl0ZXMuCiAqCSpuZXdrZXkJCUJ1ZmZlciB0byBob2xkIHRoZSBleHRyYWN0ZWQgbmV3IGtleS4KICoJKm5ld2tleV9sZW4JTGVuZ3RoIG9mIG5ld2tleSBpbiBieXRlcy4KICogICAgICAKICogUmV0dXJuczoKICoJU05NUEVSUl9TVUNDRVNTCQkJU3VjY2Vzcy4KICoJU05NUEVSUl9HRU5FUlIJCQlBbGwgZXJyb3JzLgogKgogKgogKiBEZWNvZGVzIGEgc3RyaW5nIG9mIGJpdHMgZW5jb2RlZCBhY2NvcmRpbmcgdG8gdGhlIEtleUNoYW5nZSBUQyBkZXNjcmliZWQKICogaW4gUkZDIDIyNzQsIFNlY3Rpb24gNS4gIFRoZSBuZXcga2V5IGlzIGV4dHJhY3RlZCBmcm9tICprY3N0cmluZyB3aXRoCiAqIHRoZSBhaWQgb2YgdGhlIG9sZCBrZXkuCiAqCiAqIFVwb24gc3VjY2Vzc2Z1bCByZXR1cm4sICpuZXdrZXlfbGVuIGNvbnRhaW5zIHRoZSBsZW5ndGggb2YgdGhlIG5ldyBrZXkuCiAqCiAqCiAqIEFTU1VNRVMJT2xkIGtleSBpcyBleGFjdGx5IDEvMiB0aGUgbGVuZ3RoIG9mIHRoZSBLZXlDaGFuZ2UgYnVmZmVyLAogKgkJYWx0aG91Z2ggdGhpcyBsZW5ndGggbWF5IGJlIGxlc3MgdGhhbiB0aGUgaGFzaCB0cmFuc2Zvcm0KICoJCW91dHB1dC4gIFRodXMgdGhlIG5ldyBrZXkgbGVuZ3RoIHdpbGwgYmUgZXF1YWwgdG8gdGhlIG9sZAogKgkJa2V5IGxlbmd0aC4KICovCi8qCiAqIFhYWDogIGlmIHRoZSBuZXdrZXkgaXMgbm90IGxvbmcgZW5vdWdoLCBpdCBzaG91bGQgYmUgZnJlZWQgYW5kIHJlbWFsbG9jZWQgCiAqLwppbnQKZGVjb2RlX2tleWNoYW5nZShjb25zdCBvaWQgKiBoYXNodHlwZSwgdV9pbnQgaGFzaHR5cGVfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIG9sZGtleSwgc2l6ZV90IG9sZGtleV9sZW4sCiAgICAgICAgICAgICAgICAgdV9jaGFyICoga2NzdHJpbmcsIHNpemVfdCBrY3N0cmluZ19sZW4sCiAgICAgICAgICAgICAgICAgdV9jaGFyICogbmV3a2V5LCBzaXplX3QgKiBuZXdrZXlfbGVuKQojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9QS0NTMTEpCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTOwogICAgc2l6ZV90ICAgICAgICAgIHByb3Blcmxlbmd0aCA9IDA7CiAgICBpbnQgICAgICAgICAgICAgaXByb3Blcmxlbmd0aCA9IDA7CiAgICB1X2ludCAgICAgICAgICAgbmJ5dGVzID0gMDsKCiAgICB1X2NoYXIgICAgICAgICAqYnVmcCwgdG1wX2J1ZltTTk1QX01BWEJVRl07CiAgICBzaXplX3QgICAgICAgICAgdG1wX2J1Zl9sZW4gPSBTTk1QX01BWEJVRjsKICAgIHVfY2hhciAgICAgICAgICp0bXBidWYgPSBOVUxMOwoKCgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFoYXNodHlwZSB8fCAhb2xka2V5IHx8ICFrY3N0cmluZyB8fCAhbmV3a2V5IHx8ICFuZXdrZXlfbGVuCiAgICAgICAgfHwgKG9sZGtleV9sZW4gPD0gMCkgfHwgKGtjc3RyaW5nX2xlbiA8PSAwKSB8fCAoKm5ld2tleV9sZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQoKCiAgICAvKgogICAgICogU2V0dXAgZm9yIHRoZSB0cmFuc2Zvcm0gdHlwZS4KICAgICAqLwogICAgaXByb3Blcmxlbmd0aCA9IHNjX2dldF9wcm9wZXJsZW5ndGgoaGFzaHR5cGUsIGhhc2h0eXBlX2xlbik7CiAgICBpZiAoaXByb3Blcmxlbmd0aCA9PSBTTk1QRVJSX0dFTkVSUikKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQpOwoKICAgIHByb3Blcmxlbmd0aCA9IChzaXplX3QpIGlwcm9wZXJsZW5ndGg7CgogICAgaWYgKCgob2xka2V5X2xlbiAqIDIpICE9IGtjc3RyaW5nX2xlbikgfHwgKCpuZXdrZXlfbGVuIDwgb2xka2V5X2xlbikpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQoKICAgIHByb3Blcmxlbmd0aCA9IG9sZGtleV9sZW47CiAgICAqbmV3a2V5X2xlbiA9IHByb3Blcmxlbmd0aDsKCiAgICAvKgogICAgICogVXNlIHRoZSBvbGQga2V5IGFuZCB0aGUgZ2l2ZW4gS2V5Q2hhbmdlIFRDIHN0cmluZyB0byByZWNvdmVyCiAgICAgKiB0aGUgbmV3IGtleToKICAgICAqICAgICAgLiBIYXNoIChvbGRrZXkgfCByYW5kb21fYnl0ZXMpIChpbnRvIG5ld2tleSksCiAgICAgKiAgICAgIC4gWE9SIGhhc2ggYW5kIGVuY29kZWQgKHNlY29uZCkgaGFsZiBvZiBrY3N0cmluZyAoaW50byBuZXdrZXkpLgogICAgICovCiAgICB0bXBidWYgPSAodV9jaGFyICopIG1hbGxvYyhwcm9wZXJsZW5ndGggKiAyKTsKICAgIGlmICh0bXBidWYpIHsKICAgICAgICBtZW1jcHkodG1wYnVmLCBvbGRrZXksIHByb3Blcmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHRtcGJ1ZiArIHByb3Blcmxlbmd0aCwga2NzdHJpbmcsIHByb3Blcmxlbmd0aCk7CgogICAgICAgIHJ2YWwgPSBzY19oYXNoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4sIHRtcGJ1ZiwgcHJvcGVybGVuZ3RoICogMiwKICAgICAgICAgICAgICAgICAgICAgICB0bXBfYnVmLCAmdG1wX2J1Zl9sZW4pOwogICAgICAgIFFVSVRGVU4ocnZhbCwgZGVjb2RlX2tleWNoYW5nZV9xdWl0KTsKCiAgICAgICAgbWVtY3B5KG5ld2tleSwgdG1wX2J1ZiwgcHJvcGVybGVuZ3RoKTsKICAgICAgICBidWZwID0ga2NzdHJpbmcgKyBwcm9wZXJsZW5ndGg7CiAgICAgICAgbmJ5dGVzID0gMDsKICAgICAgICB3aGlsZSAoKGludCkgKG5ieXRlcysrKSA8IHByb3Blcmxlbmd0aCkgewogICAgICAgICAgICAqbmV3a2V5KysgXj0gKmJ1ZnArKzsKICAgICAgICB9CiAgICB9CgogIGRlY29kZV9rZXljaGFuZ2VfcXVpdDoKICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIGlmIChuZXdrZXkpCiAgICAgICAgICAgIG1lbXNldChuZXdrZXksIDAsIHByb3Blcmxlbmd0aCk7CiAgICB9CiAgICBtZW1zZXQodG1wX2J1ZiwgMCwgU05NUF9NQVhCVUYpOwogICAgaWYgKHRtcGJ1ZiAhPSBOVUxMKQogICAgICAgIFNOTVBfRlJFRSh0bXBidWYpOwoKICAgIHJldHVybiBydmFsOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgZGVjb2RlX2tleWNoYW5nZSgpICovCgojZWxzZQpfS0VZVE9PTFNfTk9UX0FWQUlMQUJMRQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGludGVybmFsIG9yIG9wZW5zc2wgKi8K