LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKgogKiBrZXl0b29scy5jCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtZmVhdHVyZXMuaD4KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZmRlZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpZiBIQVZFX0RNQUxMT0NfSAojaW5jbHVkZSA8ZG1hbGxvYy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FwaS5oPgojaWZkZWYgTkVUU05NUF9VU0VfT1BFTlNTTAojCWluY2x1ZGUgPG9wZW5zc2wvaG1hYy5oPgojZWxzZQojaWZkZWYgTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L21kNS5oPgojZW5kaWYKI2VuZGlmCiNpZmRlZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9DUllQVE8KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvb3BlbnNzbF9tZDUuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvb3BlbnNzbF9zaGEuaD4KI2VuZGlmCgojaWZkZWYgTkVUU05NUF9VU0VfUEtDUzExCiNpbmNsdWRlIDxzZWN1cml0eS9jcnlwdG9raS5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NjYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L2tleXRvb2xzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS90cmFuc2Zvcm1fb2lkcy5oPgoKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHVzbV9zdXBwb3J0LCBsaWJuZXRzbm1wKQpuZXRzbm1wX2ZlYXR1cmVfY2hpbGRfb2YodXNtX2tleXRvb2xzLCB1c21fc3VwcG9ydCkKCiNpZm5kZWYgTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9VU01fS0VZVE9PTFMKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGdlbmVyYXRlX0t1CiAqCiAqIFBhcmFtZXRlcnM6CiAqCSpoYXNodHlwZQlNSUIgT0lEIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUgZm9yIGhhc2hpbmcuCiAqCSBoYXNodHlwZV9sZW4JTGVuZ3RoIG9mIE9JRCB2YWx1ZS4KICoJKlAJCVByZS1hbGxvY2F0ZWQgYnl0ZXMgb2YgcGFzc3BoYXJhc2UuCiAqCSBwcGxlbgkJTGVuZ3RoIG9mIHBhc3NwaHJhc2UuCiAqCSpLdQkJQnVmZmVyIHRvIGNvbnRhaW4gS3UuCiAqCSprdWxlbgkJTGVuZ3RoIG9mIEt1IGJ1ZmZlci4KICogICAgICAKICogUmV0dXJuczoKICoJU05NUEVSUl9TVUNDRVNTCQkJU3VjY2Vzcy4KICoJU05NUEVSUl9HRU5FUlIJCQlBbGwgZXJyb3JzLgogKgogKgogKiBDb252ZXJ0IGEgcGFzc3BocmFzZSBpbnRvIGEgbWFzdGVyIHVzZXIga2V5LCBLdSwgYWNjb3JkaW5nIHRvIHRoZQogKiBhbGdvcml0aG0gZ2l2ZW4gaW4gUkZDIDIyNzQgY29uY2VybmluZyB0aGUgU05NUHYzIFVzZXIgU2VjdXJpdHkgTW9kZWwgKFVTTSkKICogYXMgZm9sbG93czoKICoKICogRXhwYW5kIHRoZSBwYXNzcGhyYXNlIHRvIGZpbGwgdGhlIHBhc3NwaHJhc2UgYnVmZmVyIHNwYWNlLCBpZiBuZWNlc3NhcnksCiAqIGNvbmNhdGVuYXRpb24gYXMgbWFueSBkdXBsaWNhdGVzIGFzIHBvc3NpYmxlIG9mIFAgdG8gaXRzZWxmLiAgSWYgUCBpcwogKiBsYXJnZXIgdGhhbiB0aGUgYnVmZmVyIHNwYWNlLCB0cnVuY2F0ZSBpdCB0byBmaXQuCiAqCiAqIFRoZW4gaGFzaCB0aGUgcmVzdWx0IHdpdGggdGhlIGdpdmVuIGhhc2h0eXBlIHRyYW5zZm9ybS4gIFJldHVybgogKiB0aGUgcmVzdWx0IGFzIEt1LgogKgogKiBJZiBzdWNjZXNzZnVsLCBrdWxlbiBjb250YWlucyB0aGUgc2l6ZSBvZiB0aGUgaGFzaCB3cml0dGVuIHRvIEt1LgogKgogKiBOT1RFICBQYXNzcGhyYXNlcyBsZXNzIHRoYW4gVVNNX0xFTkdUSF9QX01JTiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogKgkgY2F1c2UgYW4gZXJyb3IgdG8gYmUgcmV0dXJuZWQuCiAqCSAoUHVudCB0aGlzIGNoZWNrIHRvIHRoZSBjbWRsaW5lIGFwcHM/ICBYWFgpCiAqLwppbnQKZ2VuZXJhdGVfS3UoY29uc3Qgb2lkICogaGFzaHR5cGUsIHVfaW50IGhhc2h0eXBlX2xlbiwKICAgICAgICAgICAgY29uc3QgdV9jaGFyICogUCwgc2l6ZV90IHBwbGVuLCB1X2NoYXIgKiBLdSwgc2l6ZV90ICoga3VsZW4pCiNpZiBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX0NSWVBUTykKewogICAgaW50ICAgICAgICAgICAgIHJ2YWwgPSBTTk1QRVJSX1NVQ0NFU1MsCiAgICAgICAgbmJ5dGVzID0gVVNNX0xFTkdUSF9FWFBBTkRFRF9QQVNTUEhSQVNFOwojaWYgIWRlZmluZWQoTkVUU05NUF9VU0VfT1BFTlNTTCkgJiYgXAogICAgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfSU5URVJOQUxfQ1JZUFRPKQogICAgaW50ICAgICAgICAgICAgIHJldDsKI2VuZGlmCgogICAgdV9pbnQgICAgICAgICAgIGksIHBpbmRleCA9IDA7CgogICAgdV9jaGFyICAgICAgICAgIGJ1ZltVU01fTEVOR1RIX0tVX0hBU0hCTE9DS10sICpidWZwOwoKI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKICAgIEVWUF9NRF9DVFggICAgICpjdHggPSBOVUxMOwojZWxpZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9DUllQVE8KICAgIFNIQV9DVFggY3NoYTE7CiAgICBNRDVfQ1RYIGNtZDU7CiAgICBjaGFyICAgIGNyeXB0b3R5cGUgPSAwOwojZGVmaW5lIFRZUEVfTUQ1ICAxCiNkZWZpbmUgVFlQRV9TSEExIDIKI2Vsc2UKICAgIE1Ec3RydWN0ICAgICAgICBNRDsKI2VuZGlmCiAgICAvKgogICAgICogU2FuaXR5IGNoZWNrLgogICAgICovCiAgICBpZiAoIWhhc2h0eXBlIHx8ICFQIHx8ICFLdSB8fCAha3VsZW4gfHwgKCprdWxlbiA8PSAwKQogICAgICAgIHx8IChoYXNodHlwZV9sZW4gIT0gVVNNX0xFTkdUSF9PSURfVFJBTlNGT1JNKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX0t1X3F1aXQpOwogICAgfQoKICAgIGlmIChwcGxlbiA8IFVTTV9MRU5HVEhfUF9NSU4pIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiRXJyb3I6IHBhc3NwaHJhc2UgY2hvc2VuIGlzIGJlbG93IHRoZSBsZW5ndGggIgogICAgICAgICAgICAgICAgICJyZXF1aXJlbWVudHMgb2YgdGhlIFVTTSAobWluPSVkKS5cbiIsVVNNX0xFTkdUSF9QX01JTik7CiAgICAgICAgc25tcF9zZXRfZGV0YWlsKCJUaGUgc3VwcGxpZWQgcGFzc3dvcmQgbGVuZ3RoIGlzIHRvbyBzaG9ydC4iKTsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9LdV9xdWl0KTsKICAgIH0KCgogICAgLyoKICAgICAqIFNldHVwIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUuCiAgICAgKi8KI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKCiNpZmRlZiBIQVZFX0VWUF9NRF9DVFhfQ1JFQVRFCiAgICBjdHggPSBFVlBfTURfQ1RYX2NyZWF0ZSgpOwojZWxzZQogICAgY3R4ID0gbWFsbG9jKHNpemVvZigqY3R4KSk7CiAgICBpZiAoIUVWUF9NRF9DVFhfaW5pdChjdHgpKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKI2VuZGlmCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01ENQogICAgaWYgKElTVFJBTlNGT1JNKGhhc2h0eXBlLCBITUFDTUQ1QXV0aCkpIHsKICAgICAgICBpZiAoIUVWUF9EaWdlc3RJbml0KGN0eCwgRVZQX21kNSgpKSkKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfSBlbHNlCiNlbmRpZgogICAgICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ1NIQTFBdXRoKSkgewogICAgICAgICAgICBpZiAoIUVWUF9EaWdlc3RJbml0KGN0eCwgRVZQX3NoYTEoKSkpCiAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfSBlbHNlCiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiNlbGlmIE5FVFNOTVBfVVNFX0lOVEVSTkFMX0NSWVBUTwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ01ENUF1dGgpKSB7CiAgICAgICAgaWYgKCFNRDVfSW5pdCgmY21kNSkpCiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICBjcnlwdG90eXBlID0gVFlQRV9NRDU7CiAgICB9IGVsc2UKI2VuZGlmCiAgICAgICAgICAgaWYgKElTVFJBTlNGT1JNKGhhc2h0eXBlLCBITUFDU0hBMUF1dGgpKSB7CiAgICAgICAgaWYgKCFTSEExX0luaXQoJmNzaGExKSkKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIGNyeXB0b3R5cGUgPSBUWVBFX1NIQTE7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoU05NUEVSUl9HRU5FUlIpOwogICAgfQojZWxzZQogICAgTURiZWdpbigmTUQpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfVVNFX09QRU5TU0wgKi8KCiAgICB3aGlsZSAobmJ5dGVzID4gMCkgewogICAgICAgIGJ1ZnAgPSBidWY7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLOyBpKyspIHsKICAgICAgICAgICAgKmJ1ZnArKyA9IFBbcGluZGV4KysgJSBwcGxlbl07CiAgICAgICAgfQojaWZkZWYgTkVUU05NUF9VU0VfT1BFTlNTTAogICAgICAgIEVWUF9EaWdlc3RVcGRhdGUoY3R4LCBidWYsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLKTsKI2VsaWYgTkVUU05NUF9VU0VfSU5URVJOQUxfQ1JZUFRPCiAgICAgICAgaWYgKFRZUEVfU0hBMSA9PSBjcnlwdG90eXBlKSB7CiAgICAgICAgICAgIHJ2YWwgPSAhU0hBMV9VcGRhdGUoJmNzaGExLCBidWYsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBydmFsID0gIU1ENV9VcGRhdGUoJmNtZDUsIGJ1ZiwgVVNNX0xFTkdUSF9LVV9IQVNIQkxPQ0spOwogICAgICAgIH0KICAgICAgICBpZiAocnZhbCAhPSAwKSB7CiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX1VTTV9FTkNSWVBUSU9ORVJST1I7CiAgICAgICAgfQojZWxpZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUKICAgICAgICBpZiAoTUR1cGRhdGUoJk1ELCBidWYsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLICogOCkpIHsKICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfVVNNX0VOQ1JZUFRJT05FUlJPUjsKICAgICAgICAgICAgZ290byBtZDVfZmluOwogICAgICAgIH0KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9PUEVOU1NMICovCiAgICAgICAgbmJ5dGVzIC09IFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLOwogICAgfQoKI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKICAgIHsKICAgIHVuc2lnbmVkIGludCAgICB0bXBfbGVuOwoKICAgIHRtcF9sZW4gPSAqa3VsZW47CiAgICBFVlBfRGlnZXN0RmluYWwoY3R4LCAodW5zaWduZWQgY2hhciAqKSBLdSwgJnRtcF9sZW4pOwogICAgKmt1bGVuID0gdG1wX2xlbjsKICAgIC8qCiAgICAgKiB3aGF0IGFib3V0IGZyZWUoKSAKICAgICAqLwogICAgfQojZWxpZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9DUllQVE8KICAgIGlmIChUWVBFX1NIQTEgPT0gY3J5cHRvdHlwZSkgewogICAgICAgIFNIQTFfRmluYWwoS3UsICZjc2hhMSk7CiAgICB9IGVsc2UgewogICAgICAgIE1ENV9GaW5hbChLdSwgJmNtZDUpOwogICAgfQogICAgcmV0ID0gc2NfZ2V0X3Byb3Blcmxlbmd0aChoYXNodHlwZSwgaGFzaHR5cGVfbGVuKTsKICAgIGlmIChyZXQgPT0gU05NUEVSUl9HRU5FUlIpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgKmt1bGVuID0gcmV0OwojZWxpZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUKICAgIGlmIChNRHVwZGF0ZSgmTUQsIGJ1ZiwgMCkpIHsKICAgICAgICBydmFsID0gU05NUEVSUl9VU01fRU5DUllQVElPTkVSUk9SOwogICAgICAgIGdvdG8gbWQ1X2ZpbjsKICAgIH0KICAgIHJldCA9IHNjX2dldF9wcm9wZXJsZW5ndGgoaGFzaHR5cGUsIGhhc2h0eXBlX2xlbik7CiAgICBpZiAocmV0ID09IFNOTVBFUlJfR0VORVJSKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICprdWxlbiA9IHJldDsKICAgIE1EZ2V0KCZNRCwgS3UsICprdWxlbik7CiAgbWQ1X2ZpbjoKICAgIG1lbXNldCgmTUQsIDAsIHNpemVvZihNRCkpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSAqLwoKCiNpZmRlZiBORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUKICAgIERFQlVHTVNHVEwoKCJnZW5lcmF0ZV9LdSIsICJnZW5lcmF0aW5nIEt1IChmcm9tICVzKTogIiwgUCkpOwogICAgZm9yIChpID0gMDsgaSA8ICprdWxlbjsgaSsrKQogICAgICAgIERFQlVHTVNHKCgiZ2VuZXJhdGVfS3UiLCAiJTAyeCIsIEt1W2ldKSk7CiAgICBERUJVR01TRygoImdlbmVyYXRlX0t1IiwgIlxuIikpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERSAqLwoKCiAgZ2VuZXJhdGVfS3VfcXVpdDoKICAgIG1lbXNldChidWYsIDAsIHNpemVvZihidWYpKTsKI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKICAgIGlmIChjdHgpIHsKI2lmZGVmIEhBVkVfRVZQX01EX0NUWF9ERVNUUk9ZCiAgICAgICAgRVZQX01EX0NUWF9kZXN0cm95KGN0eCk7CiNlbHNlCiAgICAgICAgRVZQX01EX0NUWF9jbGVhbnVwKGN0eCk7CiAgICAgICAgZnJlZShjdHgpOwojZW5kaWYKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gcnZhbDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGdlbmVyYXRlX0t1KCkgKi8KI2VsaWYgTkVUU05NUF9VU0VfUEtDUzExCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTOwoKICAgIC8qCiAgICAgKiBTYW5pdHkgY2hlY2suCiAgICAgKi8KICAgIGlmICghaGFzaHR5cGUgfHwgIVAgfHwgIUt1IHx8ICFrdWxlbiB8fCAoKmt1bGVuIDw9IDApCiAgICAgICAgfHwgKGhhc2h0eXBlX2xlbiAhPSBVU01fTEVOR1RIX09JRF9UUkFOU0ZPUk0pKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiAgICB9CgogICAgaWYgKHBwbGVuIDwgVVNNX0xFTkdUSF9QX01JTikgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJFcnJvcjogcGFzc3BocmFzZSBjaG9zZW4gaXMgYmVsb3cgdGhlIGxlbmd0aCAiCiAgICAgICAgICAgICAgICAgInJlcXVpcmVtZW50cyBvZiB0aGUgVVNNIChtaW49JWQpLlxuIixVU01fTEVOR1RIX1BfTUlOKTsKICAgICAgICBzbm1wX3NldF9kZXRhaWwoIlRoZSBzdXBwbGllZCBwYXNzd29yZCBsZW5ndGggaXMgdG9vIHNob3J0LiIpOwogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX0t1X3F1aXQpOwogICAgfQoKICAgIC8qCiAgICAgKiBTZXR1cCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlLgogICAgICovCgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ01ENUF1dGgpKQogICAgICAgIHJldHVybiBwa2NzX2dlbmVyYXRlX0t1KENLTV9NRDUsIFAsIHBwbGVuLCBLdSwga3VsZW4pOwogICAgZWxzZQojZW5kaWYKICAgICAgICBpZiAoSVNUUkFOU0ZPUk0oaGFzaHR5cGUsIEhNQUNTSEExQXV0aCkpCiAgICAgICAgcmV0dXJuIHBrY3NfZ2VuZXJhdGVfS3UoQ0tNX1NIQV8xLCBQLCBwcGxlbiwgS3UsIGt1bGVuKTsKICAgIGVsc2UgewogICAgICAgIHJldHVybiAoU05NUEVSUl9HRU5FUlIpOwogICAgfQoKICBnZW5lcmF0ZV9LdV9xdWl0OgoKICAgIHJldHVybiBydmFsOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBnZW5lcmF0ZV9LdSgpICovCiNlbHNlCl9LRVlUT09MU19OT1RfQVZBSUxBQkxFCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaW50ZXJuYWwgb3Igb3BlbnNzbCAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBnZW5lcmF0ZV9rdWwKICoKICogUGFyYW1ldGVyczoKICoJKmhhc2h0eXBlCiAqCSBoYXNodHlwZV9sZW4KICoJKmVuZ2luZUlECiAqCSBlbmdpbmVJRF9sZW4KICoJKkt1CQlNYXN0ZXIga2V5IGZvciBhIGdpdmVuIHVzZXIuCiAqCSBrdV9sZW4JCUxlbmd0aCBvZiBLdSBpbiBieXRlcy4KICoJKkt1bAkJTG9jYWxpemVkIGtleSBmb3IgYSBnaXZlbiB1c2VyIGF0IGVuZ2luZUlELgogKgkqa3VsX2xlbglMZW5ndGggb2YgS3VsIGJ1ZmZlciAoSU4pOyBMZW5ndGggb2YgS3VsIGtleSAoT1VUKS4KICogICAgICAKICogUmV0dXJuczoKICoJU05NUEVSUl9TVUNDRVNTCQkJU3VjY2Vzcy4KICoJU05NUEVSUl9HRU5FUlIJCQlBbGwgZXJyb3JzLgogKgogKgogKiBLdSBNVVNUIGJlIHRoZSBwcm9wZXIgbGVuZ3RoIChjdXJyZW50bHkgZml4ZWQpIGZvciB0aGUgZ2l2ZW4gaGFzaHR5cGUuCiAqCiAqIFVwb24gc3VjY2Vzc2Z1bCByZXR1cm4sIEt1bCBjb250YWlucyB0aGUgbG9jYWxpemVkIGZvcm0gb2YgS3UgYXQKICogZW5naW5lSUQsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZSBrZXkgaXMgc3RvcmVkIGluIGt1bF9sZW4uCiAqCiAqIFRoZSBsb2NhbGl6ZWQga2V5IG1ldGhvZCBpcyBkZWZpbmVkIGluIFJGQzIyNzQsIFNlY3Rpb25zIDIuNiBhbmQgQS4yLCBhbmQKICogb3JpZ2luYWxseSBkb2N1bWVudGVkIGluOgogKiAgCVUuIEJsdW1lbnRoYWwsIE4uIEMuIEhpZW4sIEIuIFdpam5lbiwKICogICAgIAkiS2V5IERlcml2YXRpb24gZm9yIE5ldHdvcmsgTWFuYWdlbWVudCBBcHBsaWNhdGlvbnMiLAogKglJRUVFIE5ldHdvcmsgTWFnYXppbmUsIEFwcmlsL01heSBpc3N1ZSwgMTk5Ny4KICoKICoKICogQVNTVU1FUyAgU05NUF9NQVhCVUYgPj0gc2l6ZW9mKEt1ICsgZW5naW5lSUQgKyBLdSkuCiAqCiAqIE5PVEUgIExvY2FsaXplZCBrZXlzIGZvciBwcml2YWN5IHRyYW5zZm9ybXMgYXJlIGdlbmVyYXRlZCB2aWEKICoJIHRoZSBhdXRoZW50aWNhdGlvbiB0cmFuc2Zvcm0gaGVsZCBieSB0aGUgc2FtZSB1c21Vc2VyLgogKgogKiBYWFgJQW4gZW5naW5lSUQgb2YgYW55IGxlbmd0aCBpcyBhY2NlcHRlZCwgZXZlbiBpZiBsYXJnZXIgdGhhbgogKgl3aGF0IGlzIHNwZWMnZWQgZm9yIHRoZSB0ZXh0dWFsIGNvbnZlbnRpb24uCiAqLwppbnQKZ2VuZXJhdGVfa3VsKGNvbnN0IG9pZCAqIGhhc2h0eXBlLCB1X2ludCBoYXNodHlwZV9sZW4sCiAgICAgICAgICAgICBjb25zdCB1X2NoYXIgKiBlbmdpbmVJRCwgc2l6ZV90IGVuZ2luZUlEX2xlbiwKICAgICAgICAgICAgIGNvbnN0IHVfY2hhciAqIEt1LCBzaXplX3Qga3VfbGVuLAogICAgICAgICAgICAgdV9jaGFyICogS3VsLCBzaXplX3QgKiBrdWxfbGVuKQojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9QS0NTMTEpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfSU5URVJOQUxfQ1JZUFRPKQp7CiAgICBpbnQgICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgIHVfaW50ICAgICAgICAgICBuYnl0ZXMgPSAwOwogICAgc2l6ZV90ICAgICAgICAgIHByb3Blcmxlbmd0aDsKICAgIGludCAgICAgICAgICAgICBpcHJvcGVybGVuZ3RoOwoKICAgIHVfY2hhciAgICAgICAgICBidWZbU05NUF9NQVhCVUZdOwojaWZkZWYgTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFCiAgICBpbnQgICAgICAgICAgICAgaTsKI2VuZGlmCgoKICAgIC8qCiAgICAgKiBTYW5pdHkgY2hlY2suCiAgICAgKi8KICAgIGlmICghaGFzaHR5cGUgfHwgIWVuZ2luZUlEIHx8ICFLdSB8fCAhS3VsIHx8ICFrdWxfbGVuCiAgICAgICAgfHwgKGVuZ2luZUlEX2xlbiA8PSAwKSB8fCAoa3VfbGVuIDw9IDApIHx8ICgqa3VsX2xlbiA8PSAwKQogICAgICAgIHx8IChoYXNodHlwZV9sZW4gIT0gVVNNX0xFTkdUSF9PSURfVFJBTlNGT1JNKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX2t1bF9xdWl0KTsKICAgIH0KCgogICAgaXByb3Blcmxlbmd0aCA9IHNjX2dldF9wcm9wZXJsZW5ndGgoaGFzaHR5cGUsIGhhc2h0eXBlX2xlbik7CiAgICBpZiAoaXByb3Blcmxlbmd0aCA9PSBTTk1QRVJSX0dFTkVSUikKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9rdWxfcXVpdCk7CgogICAgcHJvcGVybGVuZ3RoID0gKHNpemVfdCkgaXByb3Blcmxlbmd0aDsKCiAgICBpZiAoKCprdWxfbGVuIDwgcHJvcGVybGVuZ3RoKSB8fCAoa3VfbGVuIDwgcHJvcGVybGVuZ3RoKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX2t1bF9xdWl0KTsKICAgIH0KCiAgICAvKgogICAgICogQ29uY2F0ZW5hdGUgS3UgYW5kIGVuZ2luZUlEIHByb3Blcmx5LCB0aGVuIGhhc2ggdGhlIHJlc3VsdC4KICAgICAqIFN0b3JlIGl0IGluIEt1bC4KICAgICAqLwogICAgbmJ5dGVzID0gMDsKICAgIG1lbWNweShidWYsIEt1LCBwcm9wZXJsZW5ndGgpOwogICAgbmJ5dGVzICs9IHByb3Blcmxlbmd0aDsKICAgIG1lbWNweShidWYgKyBuYnl0ZXMsIGVuZ2luZUlELCBlbmdpbmVJRF9sZW4pOwogICAgbmJ5dGVzICs9IGVuZ2luZUlEX2xlbjsKICAgIG1lbWNweShidWYgKyBuYnl0ZXMsIEt1LCBwcm9wZXJsZW5ndGgpOwogICAgbmJ5dGVzICs9IHByb3Blcmxlbmd0aDsKCiAgICBydmFsID0gc2NfaGFzaChoYXNodHlwZSwgaGFzaHR5cGVfbGVuLCBidWYsIG5ieXRlcywgS3VsLCBrdWxfbGVuKTsKCiNpZmRlZiBORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUKICAgIERFQlVHTVNHVEwoKCJnZW5lcmF0ZV9rdWwiLCAiZ2VuZXJhdGluZyBLdWwgKGZyb20gS3UpOiAiKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgKmt1bF9sZW47IGkrKykKICAgICAgICBERUJVR01TRygoImdlbmVyYXRlX2t1bCIsICIlMDJ4IiwgS3VsW2ldKSk7CiAgICBERUJVR01TRygoImdlbmVyYXRlX2t1bCIsICJrZXl0b29sc1xuIikpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERSAqLwoKICAgIFFVSVRGVU4ocnZhbCwgZ2VuZXJhdGVfa3VsX3F1aXQpOwoKCiAgZ2VuZXJhdGVfa3VsX3F1aXQ6CiAgICByZXR1cm4gcnZhbDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGdlbmVyYXRlX2t1bCgpICovCgojZWxzZQpfS0VZVE9PTFNfTk9UX0FWQUlMQUJMRQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGludGVybmFsIG9yIG9wZW5zc2wgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZW5jb2RlX2tleWNoYW5nZQogKgogKiBQYXJhbWV0ZXJzOgogKgkqaGFzaHR5cGUJTUlCIE9JRCBmb3IgdGhlIGhhc2ggdHJhbnNmb3JtIHR5cGUuCiAqCSBoYXNodHlwZV9sZW4JTGVuZ3RoIG9mIHRoZSBNSUIgT0lEIGhhc2ggdHJhbnNmb3JtIHR5cGUuCiAqCSpvbGRrZXkJCU9sZCBrZXkgdGhhdCBpcyB1c2VkIHRvIGVuY29kZXMgdGhlIG5ldyBrZXkuCiAqCSBvbGRrZXlfbGVuCUxlbmd0aCBvZiBvbGRrZXkgaW4gYnl0ZXMuCiAqCSpuZXdrZXkJCU5ldyBrZXkgdGhhdCBpcyBlbmNvZGVkIHVzaW5nIHRoZSBvbGQga2V5LgogKgkgbmV3a2V5X2xlbglMZW5ndGggb2YgbmV3IGtleSBpbiBieXRlcy4KICoJKmtjc3RyaW5nCUJ1ZmZlciB0byBjb250YWluIHRoZSBLZXlDaGFuZ2UgVEMgc3RyaW5nLgogKgkqa2NzdHJpbmdfbGVuCUxlbmd0aCBvZiBrY3N0cmluZyBidWZmZXIuCiAqICAgICAgCiAqIFJldHVybnM6CiAqCVNOTVBFUlJfU1VDQ0VTUwkJCVN1Y2Nlc3MuCiAqCVNOTVBFUlJfR0VORVJSCQkJQWxsIGVycm9ycy4KICoKICoKICogVXNlcyBvbGRrZXkgYW5kIGFjcXVpcmVkIHJhbmRvbSBieXRlcyB0byBlbmNvZGUgbmV3a2V5IGludG8ga2NzdHJpbmcKICogYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBvZiB0aGUgS2V5Q2hhbmdlIFRDIGRlc2NyaWJlZCBpbiBSRkMgMjI3NCwgU2VjdGlvbiA1LgogKgogKiBVcG9uIHN1Y2Nlc3NmdWwgcmV0dXJuLCAqa2NzdHJpbmdfbGVuIGNvbnRhaW5zIHRoZSBsZW5ndGggb2YgdGhlCiAqIGVuY29kZWQgc3RyaW5nLgogKgogKiBBU1NVTUVTCU9sZCBhbmQgbmV3IGtleSBhcmUgYWx3YXlzIGVxdWFsIHRvIGVhY2ggb3RoZXIsIGFsdGhvdWdoCiAqCQl0aGlzIG1heSBiZSBsZXNzIHRoYW4gdGhlIHRyYW5zZm9ybSB0eXBlIGhhc2ggb3V0cHV0CiAqIAkJb3V0cHV0IGxlbmd0aCAoZWcsIHVzaW5nIEtleUNoYW5nZSBmb3IgYSBERVNQcml2IGtleSB3aGVuCiAqCQl0aGUgdXNlciBhbHNvIHVzZXMgU0hBMUF1dGgpLiAgVGhpcyBhbHNvIGltcGxpZXMgdGhhdCB0aGUKICoJCWhhc2ggcGxhY2VkIGluIHRoZSBzZWNvbmQgMS8yIG9mIHRoZSBrZXkgY2hhbmdlIHN0cmluZwogKgkJd2lsbCBiZSB0cnVuY2F0ZWQgYmVmb3JlIHRoZSBYT1InaW5nIHdoZW4gdGhlIGhhc2ggb3V0cHV0IGlzIAogKgkJbGFyZ2VyIHRoYW4gdGhhdCAxLzIgb2YgdGhlIGtleSBjaGFuZ2Ugc3RyaW5nLgogKgogKgkJKmtjc3RyaW5nX2xlbiB3aWxsIGJlIHJldHVybmVkIGFzIGV4YWN0bHkgdHdpY2UgdGhhdCBzYW1lCiAqCQlsZW5ndGggdGhvdWdoIHRoZSBpbnB1dCBidWZmZXIgbWF5IGJlIGxhcmdlci4KICoKICogWFhYIEZJWDogICAgIERvZXMgbm90IGhhbmRsZSB2YXJpYmFibGUgbGVuZ3RoIGtleXMuCiAqIFhYWCBGSVg6ICAgICBEb2VzIG5vdCBoYW5kbGUga2V5cyBsYXJnZXIgdGhhbiB0aGUgaGFzaCBhbGdvcml0aG0gdXNlZC4KICovCmludAplbmNvZGVfa2V5Y2hhbmdlKGNvbnN0IG9pZCAqIGhhc2h0eXBlLCB1X2ludCBoYXNodHlwZV9sZW4sCiAgICAgICAgICAgICAgICAgdV9jaGFyICogb2xka2V5LCBzaXplX3Qgb2xka2V5X2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBuZXdrZXksIHNpemVfdCBuZXdrZXlfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIGtjc3RyaW5nLCBzaXplX3QgKiBrY3N0cmluZ19sZW4pCiNpZiBkZWZpbmVkKE5FVFNOTVBfVVNFX09QRU5TU0wpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1KSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX1BLQ1MxMSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9DUllQVE8pCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTOwogICAgaW50ICAgICAgICAgICAgIGlwcm9wZXJsZW5ndGg7CiAgICBzaXplX3QgICAgICAgICAgcHJvcGVybGVuZ3RoOwogICAgc2l6ZV90ICAgICAgICAgIG5ieXRlcyA9IDA7CgogICAgdV9jaGFyICAgICAgICAgKnRtcGJ1ZiA9IE5VTEw7CgoKICAgIC8qCiAgICAgKiBTYW5pdHkgY2hlY2suCiAgICAgKi8KICAgIGlmICgha2NzdHJpbmcgfHwgIWtjc3RyaW5nX2xlbikKCXJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICBpZiAoIWhhc2h0eXBlIHx8ICFvbGRrZXkgfHwgIW5ld2tleSB8fCAha2NzdHJpbmcgfHwgIWtjc3RyaW5nX2xlbgogICAgICAgIHx8IChvbGRrZXlfbGVuIDw9IDApIHx8IChuZXdrZXlfbGVuIDw9IDApIHx8ICgqa2NzdHJpbmdfbGVuIDw9IDApCiAgICAgICAgfHwgKGhhc2h0eXBlX2xlbiAhPSBVU01fTEVOR1RIX09JRF9UUkFOU0ZPUk0pKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZW5jb2RlX2tleWNoYW5nZV9xdWl0KTsKICAgIH0KCiAgICAvKgogICAgICogU2V0dXAgZm9yIHRoZSB0cmFuc2Zvcm0gdHlwZS4KICAgICAqLwogICAgaXByb3Blcmxlbmd0aCA9IHNjX2dldF9wcm9wZXJsZW5ndGgoaGFzaHR5cGUsIGhhc2h0eXBlX2xlbik7CiAgICBpZiAoaXByb3Blcmxlbmd0aCA9PSBTTk1QRVJSX0dFTkVSUikKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwoKICAgIGlmICgob2xka2V5X2xlbiAhPSBuZXdrZXlfbGVuKSB8fCAoKmtjc3RyaW5nX2xlbiA8ICgyICogb2xka2V5X2xlbikpKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZW5jb2RlX2tleWNoYW5nZV9xdWl0KTsKICAgIH0KCiAgICBwcm9wZXJsZW5ndGggPSBTTk1QX01JTihvbGRrZXlfbGVuLCAoc2l6ZV90KWlwcm9wZXJsZW5ndGgpOwoKICAgIC8qCiAgICAgKiBVc2UgdGhlIG9sZCBrZXkgYW5kIHNvbWUgcmFuZG9tIGJ5dGVzIHRvIGVuY29kZSB0aGUgbmV3IGtleQogICAgICogaW4gdGhlIEtleUNoYW5nZSBUQyBmb3JtYXQ6CiAgICAgKiAgICAgIC4gR2V0IHJhbmRvbSBieXRlcyAoc3RvcmUgaW4gZmlyc3QgaGFsZiBvZiBrY3N0cmluZyksCiAgICAgKiAgICAgIC4gSGFzaCAob2xka2V5IHwgcmFuZG9tX2J5dGVzKSAoaW50byBzZWNvbmQgaGFsZiBvZiBrY3N0cmluZyksCiAgICAgKiAgICAgIC4gWE9SIGhhc2ggYW5kIG5ld2tleSAoaW50byBzZWNvbmQgaGFsZiBvZiBrY3N0cmluZykuCiAgICAgKgogICAgICogR2V0dGluZyB0aGUgd3JvbmcgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyBpcyBjb25zaWRlcmVkIGFuIGVycm9yLgogICAgICovCiAgICBuYnl0ZXMgPSBwcm9wZXJsZW5ndGg7CgojaWYgZGVmaW5lZChORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUpICYmIGRlZmluZWQoUkFORE9NWkVST1MpCiAgICBtZW1zZXQoa2NzdHJpbmcsIDAsIG5ieXRlcyk7CiAgICBERUJVR01TRygoImVuY29kZV9rZXljaGFuZ2UiLAogICAgICAgICAgICAgICIqKiBVc2luZyBhbGwgemVybyBiaXRzIGZvciBcInJhbmRvbVwiIGRlbHRhIG9mICkiCiAgICAgICAgICAgICAgInRoZSBrZXljaGFuZ2Ugc3RyaW5nISAqKlxuIikpOwojZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICFORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUgKi8KICAgIHJ2YWwgPSBzY19yYW5kb20oa2NzdHJpbmcsICZuYnl0ZXMpOwogICAgUVVJVEZVTihydmFsLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgaWYgKG5ieXRlcyAhPSBwcm9wZXJsZW5ndGgpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICFORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUgKi8KCiAgICB0bXBidWYgPSAodV9jaGFyICopIG1hbGxvYyhwcm9wZXJsZW5ndGggKiAyKTsKICAgIGlmICh0bXBidWYpIHsKICAgICAgICBtZW1jcHkodG1wYnVmLCBvbGRrZXksIHByb3Blcmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHRtcGJ1ZiArIHByb3Blcmxlbmd0aCwga2NzdHJpbmcsIHByb3Blcmxlbmd0aCk7CgogICAgICAgICprY3N0cmluZ19sZW4gLT0gcHJvcGVybGVuZ3RoOwogICAgICAgIHJ2YWwgPSBzY19oYXNoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4sIHRtcGJ1ZiwgcHJvcGVybGVuZ3RoICogMiwKICAgICAgICAgICAgICAgICAgICAgICBrY3N0cmluZyArIHByb3Blcmxlbmd0aCwga2NzdHJpbmdfbGVuKTsKCiAgICAgICAgUVVJVEZVTihydmFsLCBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQpOwoKICAgICAgICAqa2NzdHJpbmdfbGVuID0gKHByb3Blcmxlbmd0aCAqIDIpOwoKICAgICAgICBrY3N0cmluZyArPSBwcm9wZXJsZW5ndGg7CiAgICAgICAgbmJ5dGVzID0gMDsKICAgICAgICB3aGlsZSAoKG5ieXRlcysrKSA8IHByb3Blcmxlbmd0aCkgewogICAgICAgICAgICAqa2NzdHJpbmcrKyBePSAqbmV3a2V5Kys7CiAgICAgICAgfQogICAgfQoKICBlbmNvZGVfa2V5Y2hhbmdlX3F1aXQ6CiAgICBpZiAocnZhbCAhPSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgbWVtc2V0KGtjc3RyaW5nLCAwLCAqa2NzdHJpbmdfbGVuKTsKICAgIFNOTVBfRlJFRSh0bXBidWYpOwoKICAgIHJldHVybiBydmFsOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgZW5jb2RlX2tleWNoYW5nZSgpICovCgojZWxzZQpfS0VZVE9PTFNfTk9UX0FWQUlMQUJMRQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGludGVybmFsIG9yIG9wZW5zc2wgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZGVjb2RlX2tleWNoYW5nZQogKgogKiBQYXJhbWV0ZXJzOgogKgkqaGFzaHR5cGUJTUlCIE9JRCBvZiB0aGUgaGFzaCB0cmFuc2Zvcm0gdG8gdXNlLgogKgkgaGFzaHR5cGVfbGVuCUxlbmd0aCBvZiB0aGUgaGFzaCB0cmFuc2Zvcm0gTUlCIE9JRC4KICoJKm9sZGtleQkJT2xkIGtleSB0aGF0IGlzIHVzZWQgdG8gZW5jb2RlIHRoZSBuZXcga2V5LgogKgkgb2xka2V5X2xlbglMZW5ndGggb2Ygb2xka2V5IGluIGJ5dGVzLgogKgkqa2NzdHJpbmcJRW5jb2RlZCBLZXlTdHJpbmcgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIG5ldyBrZXkuCiAqCSBrY3N0cmluZ19sZW4JTGVuZ3RoIG9mIGtjc3RyaW5nIGluIGJ5dGVzLgogKgkqbmV3a2V5CQlCdWZmZXIgdG8gaG9sZCB0aGUgZXh0cmFjdGVkIG5ldyBrZXkuCiAqCSpuZXdrZXlfbGVuCUxlbmd0aCBvZiBuZXdrZXkgaW4gYnl0ZXMuCiAqICAgICAgCiAqIFJldHVybnM6CiAqCVNOTVBFUlJfU1VDQ0VTUwkJCVN1Y2Nlc3MuCiAqCVNOTVBFUlJfR0VORVJSCQkJQWxsIGVycm9ycy4KICoKICoKICogRGVjb2RlcyBhIHN0cmluZyBvZiBiaXRzIGVuY29kZWQgYWNjb3JkaW5nIHRvIHRoZSBLZXlDaGFuZ2UgVEMgZGVzY3JpYmVkCiAqIGluIFJGQyAyMjc0LCBTZWN0aW9uIDUuICBUaGUgbmV3IGtleSBpcyBleHRyYWN0ZWQgZnJvbSAqa2NzdHJpbmcgd2l0aAogKiB0aGUgYWlkIG9mIHRoZSBvbGQga2V5LgogKgogKiBVcG9uIHN1Y2Nlc3NmdWwgcmV0dXJuLCAqbmV3a2V5X2xlbiBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZSBuZXcga2V5LgogKgogKgogKiBBU1NVTUVTCU9sZCBrZXkgaXMgZXhhY3RseSAxLzIgdGhlIGxlbmd0aCBvZiB0aGUgS2V5Q2hhbmdlIGJ1ZmZlciwKICoJCWFsdGhvdWdoIHRoaXMgbGVuZ3RoIG1heSBiZSBsZXNzIHRoYW4gdGhlIGhhc2ggdHJhbnNmb3JtCiAqCQlvdXRwdXQuICBUaHVzIHRoZSBuZXcga2V5IGxlbmd0aCB3aWxsIGJlIGVxdWFsIHRvIHRoZSBvbGQKICoJCWtleSBsZW5ndGguCiAqLwovKgogKiBYWFg6ICBpZiB0aGUgbmV3a2V5IGlzIG5vdCBsb25nIGVub3VnaCwgaXQgc2hvdWxkIGJlIGZyZWVkIGFuZCByZW1hbGxvY2VkIAogKi8KaW50CmRlY29kZV9rZXljaGFuZ2UoY29uc3Qgb2lkICogaGFzaHR5cGUsIHVfaW50IGhhc2h0eXBlX2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBvbGRrZXksIHNpemVfdCBvbGRrZXlfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIGtjc3RyaW5nLCBzaXplX3Qga2NzdHJpbmdfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIG5ld2tleSwgc2l6ZV90ICogbmV3a2V5X2xlbikKI2lmIGRlZmluZWQoTkVUU05NUF9VU0VfT1BFTlNTTCkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfUEtDUzExKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX0NSWVBUTykKewogICAgaW50ICAgICAgICAgICAgIHJ2YWwgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICBzaXplX3QgICAgICAgICAgcHJvcGVybGVuZ3RoID0gMDsKICAgIGludCAgICAgICAgICAgICBpcHJvcGVybGVuZ3RoID0gMDsKICAgIHVfaW50ICAgICAgICAgICBuYnl0ZXMgPSAwOwoKICAgIHVfY2hhciAgICAgICAgICpidWZwLCB0bXBfYnVmW1NOTVBfTUFYQlVGXTsKICAgIHNpemVfdCAgICAgICAgICB0bXBfYnVmX2xlbiA9IFNOTVBfTUFYQlVGOwogICAgdV9jaGFyICAgICAgICAgKnRtcGJ1ZiA9IE5VTEw7CgoKCiAgICAvKgogICAgICogU2FuaXR5IGNoZWNrLgogICAgICovCiAgICBpZiAoIWhhc2h0eXBlIHx8ICFvbGRrZXkgfHwgIWtjc3RyaW5nIHx8ICFuZXdrZXkgfHwgIW5ld2tleV9sZW4KICAgICAgICB8fCAob2xka2V5X2xlbiA8PSAwKSB8fCAoa2NzdHJpbmdfbGVuIDw9IDApIHx8ICgqbmV3a2V5X2xlbiA8PSAwKQogICAgICAgIHx8IChoYXNodHlwZV9sZW4gIT0gVVNNX0xFTkdUSF9PSURfVFJBTlNGT1JNKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGRlY29kZV9rZXljaGFuZ2VfcXVpdCk7CiAgICB9CgoKICAgIC8qCiAgICAgKiBTZXR1cCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlLgogICAgICovCiAgICBpcHJvcGVybGVuZ3RoID0gc2NfZ2V0X3Byb3Blcmxlbmd0aChoYXNodHlwZSwgaGFzaHR5cGVfbGVuKTsKICAgIGlmIChpcHJvcGVybGVuZ3RoID09IFNOTVBFUlJfR0VORVJSKQogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGRlY29kZV9rZXljaGFuZ2VfcXVpdCk7CgogICAgcHJvcGVybGVuZ3RoID0gKHNpemVfdCkgaXByb3Blcmxlbmd0aDsKCiAgICBpZiAoKChvbGRrZXlfbGVuICogMikgIT0ga2NzdHJpbmdfbGVuKSB8fCAoKm5ld2tleV9sZW4gPCBvbGRrZXlfbGVuKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGRlY29kZV9rZXljaGFuZ2VfcXVpdCk7CiAgICB9CgogICAgcHJvcGVybGVuZ3RoID0gb2xka2V5X2xlbjsKICAgICpuZXdrZXlfbGVuID0gcHJvcGVybGVuZ3RoOwoKICAgIC8qCiAgICAgKiBVc2UgdGhlIG9sZCBrZXkgYW5kIHRoZSBnaXZlbiBLZXlDaGFuZ2UgVEMgc3RyaW5nIHRvIHJlY292ZXIKICAgICAqIHRoZSBuZXcga2V5OgogICAgICogICAgICAuIEhhc2ggKG9sZGtleSB8IHJhbmRvbV9ieXRlcykgKGludG8gbmV3a2V5KSwKICAgICAqICAgICAgLiBYT1IgaGFzaCBhbmQgZW5jb2RlZCAoc2Vjb25kKSBoYWxmIG9mIGtjc3RyaW5nIChpbnRvIG5ld2tleSkuCiAgICAgKi8KICAgIHRtcGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jKHByb3Blcmxlbmd0aCAqIDIpOwogICAgaWYgKHRtcGJ1ZikgewogICAgICAgIG1lbWNweSh0bXBidWYsIG9sZGtleSwgcHJvcGVybGVuZ3RoKTsKICAgICAgICBtZW1jcHkodG1wYnVmICsgcHJvcGVybGVuZ3RoLCBrY3N0cmluZywgcHJvcGVybGVuZ3RoKTsKCiAgICAgICAgcnZhbCA9IHNjX2hhc2goaGFzaHR5cGUsIGhhc2h0eXBlX2xlbiwgdG1wYnVmLCBwcm9wZXJsZW5ndGggKiAyLAogICAgICAgICAgICAgICAgICAgICAgIHRtcF9idWYsICZ0bXBfYnVmX2xlbik7CiAgICAgICAgUVVJVEZVTihydmFsLCBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQpOwoKICAgICAgICBtZW1jcHkobmV3a2V5LCB0bXBfYnVmLCBwcm9wZXJsZW5ndGgpOwogICAgICAgIGJ1ZnAgPSBrY3N0cmluZyArIHByb3Blcmxlbmd0aDsKICAgICAgICBuYnl0ZXMgPSAwOwogICAgICAgIHdoaWxlICgobmJ5dGVzKyspIDwgcHJvcGVybGVuZ3RoKSB7CiAgICAgICAgICAgICpuZXdrZXkrKyBePSAqYnVmcCsrOwogICAgICAgIH0KICAgIH0KCiAgZGVjb2RlX2tleWNoYW5nZV9xdWl0OgogICAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgaWYgKG5ld2tleSkKICAgICAgICAgICAgbWVtc2V0KG5ld2tleSwgMCwgcHJvcGVybGVuZ3RoKTsKICAgIH0KICAgIG1lbXNldCh0bXBfYnVmLCAwLCBTTk1QX01BWEJVRik7CiAgICBTTk1QX0ZSRUUodG1wYnVmKTsKCiAgICByZXR1cm4gcnZhbDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGRlY29kZV9rZXljaGFuZ2UoKSAqLwoKI2Vsc2UKX0tFWVRPT0xTX05PVF9BVkFJTEFCTEUKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbnRlcm5hbCBvciBvcGVuc3NsICovCiNlbmRpZiAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1VTTV9LRVlUT09MUyAqLwo=