LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKgogKiBrZXl0b29scy5jCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmZGVmIEhBVkVfTkVUSU5FVF9JTl9ICiNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgoKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfRE1BTExPQ19ICiNpbmNsdWRlIDxkbWFsbG9jLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL3R5cGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9vdXRwdXRfYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC91dGlsaXRpZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfYXBpLmg+CiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCiMJaW5jbHVkZSA8b3BlbnNzbC9obWFjLmg+CiNlbHNlCiNpZmRlZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvbWQ1Lmg+CiNlbmRpZgojZW5kaWYKI2lmZGVmIE5FVFNOTVBfVVNFX0lOVEVSTkFMX0NSWVBUTwojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9vcGVuc3NsX21kNS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9vcGVuc3NsX3NoYS5oPgojZW5kaWYKCiNpZmRlZiBORVRTTk1QX1VTRV9QS0NTMTEKI2luY2x1ZGUgPHNlY3VyaXR5L2NyeXB0b2tpLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc2NhcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkva2V5dG9vbHMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3RyYW5zZm9ybV9vaWRzLmg+CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBnZW5lcmF0ZV9LdQogKgogKiBQYXJhbWV0ZXJzOgogKgkqaGFzaHR5cGUJTUlCIE9JRCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlIGZvciBoYXNoaW5nLgogKgkgaGFzaHR5cGVfbGVuCUxlbmd0aCBvZiBPSUQgdmFsdWUuCiAqCSpQCQlQcmUtYWxsb2NhdGVkIGJ5dGVzIG9mIHBhc3NwaGFyYXNlLgogKgkgcHBsZW4JCUxlbmd0aCBvZiBwYXNzcGhyYXNlLgogKgkqS3UJCUJ1ZmZlciB0byBjb250YWluIEt1LgogKgkqa3VsZW4JCUxlbmd0aCBvZiBLdSBidWZmZXIuCiAqICAgICAgCiAqIFJldHVybnM6CiAqCVNOTVBFUlJfU1VDQ0VTUwkJCVN1Y2Nlc3MuCiAqCVNOTVBFUlJfR0VORVJSCQkJQWxsIGVycm9ycy4KICoKICoKICogQ29udmVydCBhIHBhc3NwaHJhc2UgaW50byBhIG1hc3RlciB1c2VyIGtleSwgS3UsIGFjY29yZGluZyB0byB0aGUKICogYWxnb3JpdGhtIGdpdmVuIGluIFJGQyAyMjc0IGNvbmNlcm5pbmcgdGhlIFNOTVB2MyBVc2VyIFNlY3VyaXR5IE1vZGVsIChVU00pCiAqIGFzIGZvbGxvd3M6CiAqCiAqIEV4cGFuZCB0aGUgcGFzc3BocmFzZSB0byBmaWxsIHRoZSBwYXNzcGhyYXNlIGJ1ZmZlciBzcGFjZSwgaWYgbmVjZXNzYXJ5LAogKiBjb25jYXRlbmF0aW9uIGFzIG1hbnkgZHVwbGljYXRlcyBhcyBwb3NzaWJsZSBvZiBQIHRvIGl0c2VsZi4gIElmIFAgaXMKICogbGFyZ2VyIHRoYW4gdGhlIGJ1ZmZlciBzcGFjZSwgdHJ1bmNhdGUgaXQgdG8gZml0LgogKgogKiBUaGVuIGhhc2ggdGhlIHJlc3VsdCB3aXRoIHRoZSBnaXZlbiBoYXNodHlwZSB0cmFuc2Zvcm0uICBSZXR1cm4KICogdGhlIHJlc3VsdCBhcyBLdS4KICoKICogSWYgc3VjY2Vzc2Z1bCwga3VsZW4gY29udGFpbnMgdGhlIHNpemUgb2YgdGhlIGhhc2ggd3JpdHRlbiB0byBLdS4KICoKICogTk9URSAgUGFzc3BocmFzZXMgbGVzcyB0aGFuIFVTTV9MRU5HVEhfUF9NSU4gY2hhcmFjdGVycyBpbiBsZW5ndGgKICoJIGNhdXNlIGFuIGVycm9yIHRvIGJlIHJldHVybmVkLgogKgkgKFB1bnQgdGhpcyBjaGVjayB0byB0aGUgY21kbGluZSBhcHBzPyAgWFhYKQogKi8KaW50CmdlbmVyYXRlX0t1KGNvbnN0IG9pZCAqIGhhc2h0eXBlLCB1X2ludCBoYXNodHlwZV9sZW4sCiAgICAgICAgICAgIGNvbnN0IHVfY2hhciAqIFAsIHNpemVfdCBwcGxlbiwgdV9jaGFyICogS3UsIHNpemVfdCAqIGt1bGVuKQojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfT1BFTlNTTCkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9DUllQVE8pCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTLAogICAgICAgIG5ieXRlcyA9IFVTTV9MRU5HVEhfRVhQQU5ERURfUEFTU1BIUkFTRTsKI2lmICFkZWZpbmVkKE5FVFNOTVBfVVNFX09QRU5TU0wpICYmIFwKICAgIGRlZmluZWQoTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1KSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX0NSWVBUTykKICAgIGludCAgICAgICAgICAgICByZXQ7CiNlbmRpZgoKICAgIHVfaW50ICAgICAgICAgICBpLCBwaW5kZXggPSAwOwoKICAgIHVfY2hhciAgICAgICAgICBidWZbVVNNX0xFTkdUSF9LVV9IQVNIQkxPQ0tdLCAqYnVmcDsKCiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCiAgICBFVlBfTURfQ1RYICAgICAqY3R4ID0gTlVMTDsKI2VsaWYgTkVUU05NUF9VU0VfSU5URVJOQUxfQ1JZUFRPCiAgICBTSEFfQ1RYIGNzaGExOwogICAgTUQ1X0NUWCBjbWQ1OwogICAgY2hhciAgICBjcnlwdG90eXBlID0gMDsKI2RlZmluZSBUWVBFX01ENSAgMQojZGVmaW5lIFRZUEVfU0hBMSAyCiNlbHNlCiAgICBNRHN0cnVjdCAgICAgICAgTUQ7CiNlbmRpZgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFoYXNodHlwZSB8fCAhUCB8fCAhS3UgfHwgIWt1bGVuIHx8ICgqa3VsZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9LdV9xdWl0KTsKICAgIH0KCiAgICBpZiAocHBsZW4gPCBVU01fTEVOR1RIX1BfTUlOKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkVycm9yOiBwYXNzcGhyYXNlIGNob3NlbiBpcyBiZWxvdyB0aGUgbGVuZ3RoICIKICAgICAgICAgICAgICAgICAicmVxdWlyZW1lbnRzIG9mIHRoZSBVU00gKG1pbj0lZCkuXG4iLFVTTV9MRU5HVEhfUF9NSU4pOwogICAgICAgIHNubXBfc2V0X2RldGFpbCgiVGhlIHN1cHBsaWVkIHBhc3N3b3JkIGxlbmd0aCBpcyB0b28gc2hvcnQuIik7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfS3VfcXVpdCk7CiAgICB9CgoKICAgIC8qCiAgICAgKiBTZXR1cCBmb3IgdGhlIHRyYW5zZm9ybSB0eXBlLgogICAgICovCiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCgojaWZkZWYgSEFWRV9FVlBfTURfQ1RYX0NSRUFURQogICAgY3R4ID0gRVZQX01EX0NUWF9jcmVhdGUoKTsKI2Vsc2UKICAgIGN0eCA9IG1hbGxvYyhzaXplb2YoKmN0eCkpOwogICAgaWYgKCFFVlBfTURfQ1RYX2luaXQoY3R4KSkKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiNlbmRpZgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ01ENUF1dGgpKSB7CiAgICAgICAgaWYgKCFFVlBfRGlnZXN0SW5pdChjdHgsIEVWUF9tZDUoKSkpCiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0gZWxzZQojZW5kaWYKICAgICAgICBpZiAoSVNUUkFOU0ZPUk0oaGFzaHR5cGUsIEhNQUNTSEExQXV0aCkpIHsKICAgICAgICAgICAgaWYgKCFFVlBfRGlnZXN0SW5pdChjdHgsIEVWUF9zaGExKCkpKQogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0gZWxzZQogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX0t1X3F1aXQpOwojZWxpZiBORVRTTk1QX1VTRV9JTlRFUk5BTF9DUllQVE8KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUQ1CiAgICBpZiAoSVNUUkFOU0ZPUk0oaGFzaHR5cGUsIEhNQUNNRDVBdXRoKSkgewogICAgICAgIGlmICghTUQ1X0luaXQoJmNtZDUpKQogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgY3J5cHRvdHlwZSA9IFRZUEVfTUQ1OwogICAgfSBlbHNlCiNlbmRpZgogICAgICAgICAgIGlmIChJU1RSQU5TRk9STShoYXNodHlwZSwgSE1BQ1NIQTFBdXRoKSkgewogICAgICAgIGlmICghU0hBMV9Jbml0KCZjc2hhMSkpCiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICBjcnlwdG90eXBlID0gVFlQRV9TSEExOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKFNOTVBFUlJfR0VORVJSKTsKICAgIH0KI2Vsc2UKICAgIE1EYmVnaW4oJk1EKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9PUEVOU1NMICovCgogICAgd2hpbGUgKG5ieXRlcyA+IDApIHsKICAgICAgICBidWZwID0gYnVmOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSzsgaSsrKSB7CiAgICAgICAgICAgICpidWZwKysgPSBQW3BpbmRleCsrICUgcHBsZW5dOwogICAgICAgIH0KI2lmZGVmIE5FVFNOTVBfVVNFX09QRU5TU0wKICAgICAgICBFVlBfRGlnZXN0VXBkYXRlKGN0eCwgYnVmLCBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSyk7CiNlbGlmIE5FVFNOTVBfVVNFX0lOVEVSTkFMX0NSWVBUTwogICAgICAgIGlmIChUWVBFX1NIQTEgPT0gY3J5cHRvdHlwZSkgewogICAgICAgICAgICBydmFsID0gIVNIQTFfVXBkYXRlKCZjc2hhMSwgYnVmLCBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcnZhbCA9ICFNRDVfVXBkYXRlKCZjbWQ1LCBidWYsIFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJ2YWwgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9VU01fRU5DUllQVElPTkVSUk9SOwogICAgICAgIH0KI2VsaWYgTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1CiAgICAgICAgaWYgKE1EdXBkYXRlKCZNRCwgYnVmLCBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSyAqIDgpKSB7CiAgICAgICAgICAgIHJ2YWwgPSBTTk1QRVJSX1VTTV9FTkNSWVBUSU9ORVJST1I7CiAgICAgICAgICAgIGdvdG8gbWQ1X2ZpbjsKICAgICAgICB9CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfT1BFTlNTTCAqLwogICAgICAgIG5ieXRlcyAtPSBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSzsKICAgIH0KCiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCiAgICB7CiAgICB1bnNpZ25lZCBpbnQgICAgdG1wX2xlbjsKCiAgICB0bXBfbGVuID0gKmt1bGVuOwogICAgRVZQX0RpZ2VzdEZpbmFsKGN0eCwgKHVuc2lnbmVkIGNoYXIgKikgS3UsICZ0bXBfbGVuKTsKICAgICprdWxlbiA9IHRtcF9sZW47CiAgICAvKgogICAgICogd2hhdCBhYm91dCBmcmVlKCkgCiAgICAgKi8KICAgIH0KI2VsaWYgTkVUU05NUF9VU0VfSU5URVJOQUxfQ1JZUFRPCiAgICBpZiAoVFlQRV9TSEExID09IGNyeXB0b3R5cGUpIHsKICAgICAgICBTSEExX0ZpbmFsKEt1LCAmY3NoYTEpOwogICAgfSBlbHNlIHsKICAgICAgICBNRDVfRmluYWwoS3UsICZjbWQ1KTsKICAgIH0KICAgIHJldCA9IHNjX2dldF9wcm9wZXJsZW5ndGgoaGFzaHR5cGUsIGhhc2h0eXBlX2xlbik7CiAgICBpZiAocmV0ID09IFNOTVBFUlJfR0VORVJSKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICprdWxlbiA9IHJldDsKI2VsaWYgTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1CiAgICBpZiAoTUR1cGRhdGUoJk1ELCBidWYsIDApKSB7CiAgICAgICAgcnZhbCA9IFNOTVBFUlJfVVNNX0VOQ1JZUFRJT05FUlJPUjsKICAgICAgICBnb3RvIG1kNV9maW47CiAgICB9CiAgICByZXQgPSBzY19nZXRfcHJvcGVybGVuZ3RoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4pOwogICAgaWYgKHJldCA9PSBTTk1QRVJSX0dFTkVSUikKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAqa3VsZW4gPSByZXQ7CiAgICBNRGdldCgmTUQsIEt1LCAqa3VsZW4pOwogIG1kNV9maW46CiAgICBtZW1zZXQoJk1ELCAwLCBzaXplb2YoTUQpKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUgKi8KCgojaWZkZWYgTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFCiAgICBERUJVR01TR1RMKCgiZ2VuZXJhdGVfS3UiLCAiZ2VuZXJhdGluZyBLdSAoZnJvbSAlcyk6ICIsIFApKTsKICAgIGZvciAoaSA9IDA7IGkgPCAqa3VsZW47IGkrKykKICAgICAgICBERUJVR01TRygoImdlbmVyYXRlX0t1IiwgIiUwMngiLCBLdVtpXSkpOwogICAgREVCVUdNU0coKCJnZW5lcmF0ZV9LdSIsICJcbiIpKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUgKi8KCgogIGdlbmVyYXRlX0t1X3F1aXQ6CiAgICBtZW1zZXQoYnVmLCAwLCBzaXplb2YoYnVmKSk7CiNpZmRlZiBORVRTTk1QX1VTRV9PUEVOU1NMCiAgICBpZiAoY3R4KSB7CiNpZmRlZiBIQVZFX0VWUF9NRF9DVFhfREVTVFJPWQogICAgICAgIEVWUF9NRF9DVFhfZGVzdHJveShjdHgpOwojZWxzZQogICAgICAgIEVWUF9NRF9DVFhfY2xlYW51cChjdHgpOwogICAgICAgIGZyZWUoY3R4KTsKI2VuZGlmCiAgICB9CiNlbmRpZgogICAgcmV0dXJuIHJ2YWw7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBnZW5lcmF0ZV9LdSgpICovCiNlbGlmIE5FVFNOTVBfVVNFX1BLQ1MxMQp7CiAgICBpbnQgICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfU1VDQ0VTUzsKCiAgICAvKgogICAgICogU2FuaXR5IGNoZWNrLgogICAgICovCiAgICBpZiAoIWhhc2h0eXBlIHx8ICFQIHx8ICFLdSB8fCAha3VsZW4gfHwgKCprdWxlbiA8PSAwKQogICAgICAgIHx8IChoYXNodHlwZV9sZW4gIT0gVVNNX0xFTkdUSF9PSURfVFJBTlNGT1JNKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGdlbmVyYXRlX0t1X3F1aXQpOwogICAgfQoKICAgIGlmIChwcGxlbiA8IFVTTV9MRU5HVEhfUF9NSU4pIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiRXJyb3I6IHBhc3NwaHJhc2UgY2hvc2VuIGlzIGJlbG93IHRoZSBsZW5ndGggIgogICAgICAgICAgICAgICAgICJyZXF1aXJlbWVudHMgb2YgdGhlIFVTTSAobWluPSVkKS5cbiIsVVNNX0xFTkdUSF9QX01JTik7CiAgICAgICAgc25tcF9zZXRfZGV0YWlsKCJUaGUgc3VwcGxpZWQgcGFzc3dvcmQgbGVuZ3RoIGlzIHRvbyBzaG9ydC4iKTsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9LdV9xdWl0KTsKICAgIH0KCiAgICAvKgogICAgICogU2V0dXAgZm9yIHRoZSB0cmFuc2Zvcm0gdHlwZS4KICAgICAqLwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUQ1CiAgICBpZiAoSVNUUkFOU0ZPUk0oaGFzaHR5cGUsIEhNQUNNRDVBdXRoKSkKICAgICAgICByZXR1cm4gcGtjc19nZW5lcmF0ZV9LdShDS01fTUQ1LCBQLCBwcGxlbiwgS3UsIGt1bGVuKTsKICAgIGVsc2UKI2VuZGlmCiAgICAgICAgaWYgKElTVFJBTlNGT1JNKGhhc2h0eXBlLCBITUFDU0hBMUF1dGgpKQogICAgICAgIHJldHVybiBwa2NzX2dlbmVyYXRlX0t1KENLTV9TSEFfMSwgUCwgcHBsZW4sIEt1LCBrdWxlbik7CiAgICBlbHNlIHsKICAgICAgICByZXR1cm4gKFNOTVBFUlJfR0VORVJSKTsKICAgIH0KCiAgZ2VuZXJhdGVfS3VfcXVpdDoKCiAgICByZXR1cm4gcnZhbDsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgZ2VuZXJhdGVfS3UoKSAqLwojZWxzZQpfS0VZVE9PTFNfTk9UX0FWQUlMQUJMRQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGludGVybmFsIG9yIG9wZW5zc2wgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZ2VuZXJhdGVfa3VsCiAqCiAqIFBhcmFtZXRlcnM6CiAqCSpoYXNodHlwZQogKgkgaGFzaHR5cGVfbGVuCiAqCSplbmdpbmVJRAogKgkgZW5naW5lSURfbGVuCiAqCSpLdQkJTWFzdGVyIGtleSBmb3IgYSBnaXZlbiB1c2VyLgogKgkga3VfbGVuCQlMZW5ndGggb2YgS3UgaW4gYnl0ZXMuCiAqCSpLdWwJCUxvY2FsaXplZCBrZXkgZm9yIGEgZ2l2ZW4gdXNlciBhdCBlbmdpbmVJRC4KICoJKmt1bF9sZW4JTGVuZ3RoIG9mIEt1bCBidWZmZXIgKElOKTsgTGVuZ3RoIG9mIEt1bCBrZXkgKE9VVCkuCiAqICAgICAgCiAqIFJldHVybnM6CiAqCVNOTVBFUlJfU1VDQ0VTUwkJCVN1Y2Nlc3MuCiAqCVNOTVBFUlJfR0VORVJSCQkJQWxsIGVycm9ycy4KICoKICoKICogS3UgTVVTVCBiZSB0aGUgcHJvcGVyIGxlbmd0aCAoY3VycmVudGx5IGZpeGVkKSBmb3IgdGhlIGdpdmVuIGhhc2h0eXBlLgogKgogKiBVcG9uIHN1Y2Nlc3NmdWwgcmV0dXJuLCBLdWwgY29udGFpbnMgdGhlIGxvY2FsaXplZCBmb3JtIG9mIEt1IGF0CiAqIGVuZ2luZUlELCBhbmQgdGhlIGxlbmd0aCBvZiB0aGUga2V5IGlzIHN0b3JlZCBpbiBrdWxfbGVuLgogKgogKiBUaGUgbG9jYWxpemVkIGtleSBtZXRob2QgaXMgZGVmaW5lZCBpbiBSRkMyMjc0LCBTZWN0aW9ucyAyLjYgYW5kIEEuMiwgYW5kCiAqIG9yaWdpbmFsbHkgZG9jdW1lbnRlZCBpbjoKICogIAlVLiBCbHVtZW50aGFsLCBOLiBDLiBIaWVuLCBCLiBXaWpuZW4sCiAqICAgICAJIktleSBEZXJpdmF0aW9uIGZvciBOZXR3b3JrIE1hbmFnZW1lbnQgQXBwbGljYXRpb25zIiwKICoJSUVFRSBOZXR3b3JrIE1hZ2F6aW5lLCBBcHJpbC9NYXkgaXNzdWUsIDE5OTcuCiAqCiAqCiAqIEFTU1VNRVMgIFNOTVBfTUFYQlVGID49IHNpemVvZihLdSArIGVuZ2luZUlEICsgS3UpLgogKgogKiBOT1RFICBMb2NhbGl6ZWQga2V5cyBmb3IgcHJpdmFjeSB0cmFuc2Zvcm1zIGFyZSBnZW5lcmF0ZWQgdmlhCiAqCSB0aGUgYXV0aGVudGljYXRpb24gdHJhbnNmb3JtIGhlbGQgYnkgdGhlIHNhbWUgdXNtVXNlci4KICoKICogWFhYCUFuIGVuZ2luZUlEIG9mIGFueSBsZW5ndGggaXMgYWNjZXB0ZWQsIGV2ZW4gaWYgbGFyZ2VyIHRoYW4KICoJd2hhdCBpcyBzcGVjJ2VkIGZvciB0aGUgdGV4dHVhbCBjb252ZW50aW9uLgogKi8KaW50CmdlbmVyYXRlX2t1bChjb25zdCBvaWQgKiBoYXNodHlwZSwgdV9pbnQgaGFzaHR5cGVfbGVuLAogICAgICAgICAgICAgY29uc3QgdV9jaGFyICogZW5naW5lSUQsIHNpemVfdCBlbmdpbmVJRF9sZW4sCiAgICAgICAgICAgICBjb25zdCB1X2NoYXIgKiBLdSwgc2l6ZV90IGt1X2xlbiwKICAgICAgICAgICAgIHVfY2hhciAqIEt1bCwgc2l6ZV90ICoga3VsX2xlbikKI2lmIGRlZmluZWQoTkVUU05NUF9VU0VfT1BFTlNTTCkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9NRDUpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfUEtDUzExKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX0NSWVBUTykKewogICAgaW50ICAgICAgICAgICAgIHJ2YWwgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICB1X2ludCAgICAgICAgICAgbmJ5dGVzID0gMDsKICAgIHNpemVfdCAgICAgICAgICBwcm9wZXJsZW5ndGg7CiAgICBpbnQgICAgICAgICAgICAgaXByb3Blcmxlbmd0aDsKCiAgICB1X2NoYXIgICAgICAgICAgYnVmW1NOTVBfTUFYQlVGXTsKI2lmZGVmIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERQogICAgaW50ICAgICAgICAgICAgIGk7CiNlbmRpZgoKCiAgICAvKgogICAgICogU2FuaXR5IGNoZWNrLgogICAgICovCiAgICBpZiAoIWhhc2h0eXBlIHx8ICFlbmdpbmVJRCB8fCAhS3UgfHwgIUt1bCB8fCAha3VsX2xlbgogICAgICAgIHx8IChlbmdpbmVJRF9sZW4gPD0gMCkgfHwgKGt1X2xlbiA8PSAwKSB8fCAoKmt1bF9sZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9rdWxfcXVpdCk7CiAgICB9CgoKICAgIGlwcm9wZXJsZW5ndGggPSBzY19nZXRfcHJvcGVybGVuZ3RoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4pOwogICAgaWYgKGlwcm9wZXJsZW5ndGggPT0gU05NUEVSUl9HRU5FUlIpCiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZ2VuZXJhdGVfa3VsX3F1aXQpOwoKICAgIHByb3Blcmxlbmd0aCA9IChzaXplX3QpIGlwcm9wZXJsZW5ndGg7CgogICAgaWYgKCgqa3VsX2xlbiA8IHByb3Blcmxlbmd0aCkgfHwgKGt1X2xlbiA8IHByb3Blcmxlbmd0aCkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBnZW5lcmF0ZV9rdWxfcXVpdCk7CiAgICB9CgogICAgLyoKICAgICAqIENvbmNhdGVuYXRlIEt1IGFuZCBlbmdpbmVJRCBwcm9wZXJseSwgdGhlbiBoYXNoIHRoZSByZXN1bHQuCiAgICAgKiBTdG9yZSBpdCBpbiBLdWwuCiAgICAgKi8KICAgIG5ieXRlcyA9IDA7CiAgICBtZW1jcHkoYnVmLCBLdSwgcHJvcGVybGVuZ3RoKTsKICAgIG5ieXRlcyArPSBwcm9wZXJsZW5ndGg7CiAgICBtZW1jcHkoYnVmICsgbmJ5dGVzLCBlbmdpbmVJRCwgZW5naW5lSURfbGVuKTsKICAgIG5ieXRlcyArPSBlbmdpbmVJRF9sZW47CiAgICBtZW1jcHkoYnVmICsgbmJ5dGVzLCBLdSwgcHJvcGVybGVuZ3RoKTsKICAgIG5ieXRlcyArPSBwcm9wZXJsZW5ndGg7CgogICAgcnZhbCA9IHNjX2hhc2goaGFzaHR5cGUsIGhhc2h0eXBlX2xlbiwgYnVmLCBuYnl0ZXMsIEt1bCwga3VsX2xlbik7CgojaWZkZWYgTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFCiAgICBERUJVR01TR1RMKCgiZ2VuZXJhdGVfa3VsIiwgImdlbmVyYXRpbmcgS3VsIChmcm9tIEt1KTogIikpOwogICAgZm9yIChpID0gMDsgaSA8ICprdWxfbGVuOyBpKyspCiAgICAgICAgREVCVUdNU0coKCJnZW5lcmF0ZV9rdWwiLCAiJTAyeCIsIEt1bFtpXSkpOwogICAgREVCVUdNU0coKCJnZW5lcmF0ZV9rdWwiLCAia2V5dG9vbHNcbiIpKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX0VOQUJMRV9URVNUSU5HX0NPREUgKi8KCiAgICBRVUlURlVOKHJ2YWwsIGdlbmVyYXRlX2t1bF9xdWl0KTsKCgogIGdlbmVyYXRlX2t1bF9xdWl0OgogICAgcmV0dXJuIHJ2YWw7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBnZW5lcmF0ZV9rdWwoKSAqLwoKI2Vsc2UKX0tFWVRPT0xTX05PVF9BVkFJTEFCTEUKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbnRlcm5hbCBvciBvcGVuc3NsICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGVuY29kZV9rZXljaGFuZ2UKICoKICogUGFyYW1ldGVyczoKICoJKmhhc2h0eXBlCU1JQiBPSUQgZm9yIHRoZSBoYXNoIHRyYW5zZm9ybSB0eXBlLgogKgkgaGFzaHR5cGVfbGVuCUxlbmd0aCBvZiB0aGUgTUlCIE9JRCBoYXNoIHRyYW5zZm9ybSB0eXBlLgogKgkqb2xka2V5CQlPbGQga2V5IHRoYXQgaXMgdXNlZCB0byBlbmNvZGVzIHRoZSBuZXcga2V5LgogKgkgb2xka2V5X2xlbglMZW5ndGggb2Ygb2xka2V5IGluIGJ5dGVzLgogKgkqbmV3a2V5CQlOZXcga2V5IHRoYXQgaXMgZW5jb2RlZCB1c2luZyB0aGUgb2xkIGtleS4KICoJIG5ld2tleV9sZW4JTGVuZ3RoIG9mIG5ldyBrZXkgaW4gYnl0ZXMuCiAqCSprY3N0cmluZwlCdWZmZXIgdG8gY29udGFpbiB0aGUgS2V5Q2hhbmdlIFRDIHN0cmluZy4KICoJKmtjc3RyaW5nX2xlbglMZW5ndGggb2Yga2NzdHJpbmcgYnVmZmVyLgogKiAgICAgIAogKiBSZXR1cm5zOgogKglTTk1QRVJSX1NVQ0NFU1MJCQlTdWNjZXNzLgogKglTTk1QRVJSX0dFTkVSUgkJCUFsbCBlcnJvcnMuCiAqCiAqCiAqIFVzZXMgb2xka2V5IGFuZCBhY3F1aXJlZCByYW5kb20gYnl0ZXMgdG8gZW5jb2RlIG5ld2tleSBpbnRvIGtjc3RyaW5nCiAqIGFjY29yZGluZyB0byB0aGUgcnVsZXMgb2YgdGhlIEtleUNoYW5nZSBUQyBkZXNjcmliZWQgaW4gUkZDIDIyNzQsIFNlY3Rpb24gNS4KICoKICogVXBvbiBzdWNjZXNzZnVsIHJldHVybiwgKmtjc3RyaW5nX2xlbiBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZQogKiBlbmNvZGVkIHN0cmluZy4KICoKICogQVNTVU1FUwlPbGQgYW5kIG5ldyBrZXkgYXJlIGFsd2F5cyBlcXVhbCB0byBlYWNoIG90aGVyLCBhbHRob3VnaAogKgkJdGhpcyBtYXkgYmUgbGVzcyB0aGFuIHRoZSB0cmFuc2Zvcm0gdHlwZSBoYXNoIG91dHB1dAogKiAJCW91dHB1dCBsZW5ndGggKGVnLCB1c2luZyBLZXlDaGFuZ2UgZm9yIGEgREVTUHJpdiBrZXkgd2hlbgogKgkJdGhlIHVzZXIgYWxzbyB1c2VzIFNIQTFBdXRoKS4gIFRoaXMgYWxzbyBpbXBsaWVzIHRoYXQgdGhlCiAqCQloYXNoIHBsYWNlZCBpbiB0aGUgc2Vjb25kIDEvMiBvZiB0aGUga2V5IGNoYW5nZSBzdHJpbmcKICoJCXdpbGwgYmUgdHJ1bmNhdGVkIGJlZm9yZSB0aGUgWE9SJ2luZyB3aGVuIHRoZSBoYXNoIG91dHB1dCBpcyAKICoJCWxhcmdlciB0aGFuIHRoYXQgMS8yIG9mIHRoZSBrZXkgY2hhbmdlIHN0cmluZy4KICoKICoJCSprY3N0cmluZ19sZW4gd2lsbCBiZSByZXR1cm5lZCBhcyBleGFjdGx5IHR3aWNlIHRoYXQgc2FtZQogKgkJbGVuZ3RoIHRob3VnaCB0aGUgaW5wdXQgYnVmZmVyIG1heSBiZSBsYXJnZXIuCiAqCiAqIFhYWCBGSVg6ICAgICBEb2VzIG5vdCBoYW5kbGUgdmFyaWJhYmxlIGxlbmd0aCBrZXlzLgogKiBYWFggRklYOiAgICAgRG9lcyBub3QgaGFuZGxlIGtleXMgbGFyZ2VyIHRoYW4gdGhlIGhhc2ggYWxnb3JpdGhtIHVzZWQuCiAqLwppbnQKZW5jb2RlX2tleWNoYW5nZShjb25zdCBvaWQgKiBoYXNodHlwZSwgdV9pbnQgaGFzaHR5cGVfbGVuLAogICAgICAgICAgICAgICAgIHVfY2hhciAqIG9sZGtleSwgc2l6ZV90IG9sZGtleV9sZW4sCiAgICAgICAgICAgICAgICAgdV9jaGFyICogbmV3a2V5LCBzaXplX3QgbmV3a2V5X2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBrY3N0cmluZywgc2l6ZV90ICoga2NzdHJpbmdfbGVuKQojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX0lOVEVSTkFMX01ENSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9QS0NTMTEpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfSU5URVJOQUxfQ1JZUFRPKQp7CiAgICBpbnQgICAgICAgICAgICAgcnZhbCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgIGludCAgICAgICAgICAgICBpcHJvcGVybGVuZ3RoOwogICAgc2l6ZV90ICAgICAgICAgIHByb3Blcmxlbmd0aDsKICAgIHNpemVfdCAgICAgICAgICBuYnl0ZXMgPSAwOwoKICAgIHVfY2hhciAgICAgICAgICp0bXBidWYgPSBOVUxMOwoKCiAgICAvKgogICAgICogU2FuaXR5IGNoZWNrLgogICAgICovCiAgICBpZiAoIWtjc3RyaW5nIHx8ICFrY3N0cmluZ19sZW4pCglyZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgaWYgKCFoYXNodHlwZSB8fCAhb2xka2V5IHx8ICFuZXdrZXkgfHwgIWtjc3RyaW5nIHx8ICFrY3N0cmluZ19sZW4KICAgICAgICB8fCAob2xka2V5X2xlbiA8PSAwKSB8fCAobmV3a2V5X2xlbiA8PSAwKSB8fCAoKmtjc3RyaW5nX2xlbiA8PSAwKQogICAgICAgIHx8IChoYXNodHlwZV9sZW4gIT0gVVNNX0xFTkdUSF9PSURfVFJBTlNGT1JNKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGVuY29kZV9rZXljaGFuZ2VfcXVpdCk7CiAgICB9CgogICAgLyoKICAgICAqIFNldHVwIGZvciB0aGUgdHJhbnNmb3JtIHR5cGUuCiAgICAgKi8KICAgIGlwcm9wZXJsZW5ndGggPSBzY19nZXRfcHJvcGVybGVuZ3RoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4pOwogICAgaWYgKGlwcm9wZXJsZW5ndGggPT0gU05NUEVSUl9HRU5FUlIpCiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZW5jb2RlX2tleWNoYW5nZV9xdWl0KTsKCiAgICBpZiAoKG9sZGtleV9sZW4gIT0gbmV3a2V5X2xlbikgfHwgKCprY3N0cmluZ19sZW4gPCAoMiAqIG9sZGtleV9sZW4pKSkgewogICAgICAgIFFVSVRGVU4oU05NUEVSUl9HRU5FUlIsIGVuY29kZV9rZXljaGFuZ2VfcXVpdCk7CiAgICB9CgogICAgcHJvcGVybGVuZ3RoID0gU05NUF9NSU4ob2xka2V5X2xlbiwgKHNpemVfdClpcHJvcGVybGVuZ3RoKTsKCiAgICAvKgogICAgICogVXNlIHRoZSBvbGQga2V5IGFuZCBzb21lIHJhbmRvbSBieXRlcyB0byBlbmNvZGUgdGhlIG5ldyBrZXkKICAgICAqIGluIHRoZSBLZXlDaGFuZ2UgVEMgZm9ybWF0OgogICAgICogICAgICAuIEdldCByYW5kb20gYnl0ZXMgKHN0b3JlIGluIGZpcnN0IGhhbGYgb2Yga2NzdHJpbmcpLAogICAgICogICAgICAuIEhhc2ggKG9sZGtleSB8IHJhbmRvbV9ieXRlcykgKGludG8gc2Vjb25kIGhhbGYgb2Yga2NzdHJpbmcpLAogICAgICogICAgICAuIFhPUiBoYXNoIGFuZCBuZXdrZXkgKGludG8gc2Vjb25kIGhhbGYgb2Yga2NzdHJpbmcpLgogICAgICoKICAgICAqIEdldHRpbmcgdGhlIHdyb25nIG51bWJlciBvZiByYW5kb20gYnl0ZXMgaXMgY29uc2lkZXJlZCBhbiBlcnJvci4KICAgICAqLwogICAgbmJ5dGVzID0gcHJvcGVybGVuZ3RoOwoKI2lmIGRlZmluZWQoTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFKSAmJiBkZWZpbmVkKFJBTkRPTVpFUk9TKQogICAgbWVtc2V0KGtjc3RyaW5nLCAwLCBuYnl0ZXMpOwogICAgREVCVUdNU0coKCJlbmNvZGVfa2V5Y2hhbmdlIiwKICAgICAgICAgICAgICAiKiogVXNpbmcgYWxsIHplcm8gYml0cyBmb3IgXCJyYW5kb21cIiBkZWx0YSBvZiApIgogICAgICAgICAgICAgICJ0aGUga2V5Y2hhbmdlIHN0cmluZyEgKipcbiIpKTsKI2Vsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAhTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFICovCiAgICBydmFsID0gc2NfcmFuZG9tKGtjc3RyaW5nLCAmbmJ5dGVzKTsKICAgIFFVSVRGVU4ocnZhbCwgZW5jb2RlX2tleWNoYW5nZV9xdWl0KTsKICAgIGlmIChuYnl0ZXMgIT0gcHJvcGVybGVuZ3RoKSB7CiAgICAgICAgUVVJVEZVTihTTk1QRVJSX0dFTkVSUiwgZW5jb2RlX2tleWNoYW5nZV9xdWl0KTsKICAgIH0KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAhTkVUU05NUF9FTkFCTEVfVEVTVElOR19DT0RFICovCgogICAgdG1wYnVmID0gKHVfY2hhciAqKSBtYWxsb2MocHJvcGVybGVuZ3RoICogMik7CiAgICBpZiAodG1wYnVmKSB7CiAgICAgICAgbWVtY3B5KHRtcGJ1Ziwgb2xka2V5LCBwcm9wZXJsZW5ndGgpOwogICAgICAgIG1lbWNweSh0bXBidWYgKyBwcm9wZXJsZW5ndGgsIGtjc3RyaW5nLCBwcm9wZXJsZW5ndGgpOwoKICAgICAgICAqa2NzdHJpbmdfbGVuIC09IHByb3Blcmxlbmd0aDsKICAgICAgICBydmFsID0gc2NfaGFzaChoYXNodHlwZSwgaGFzaHR5cGVfbGVuLCB0bXBidWYsIHByb3Blcmxlbmd0aCAqIDIsCiAgICAgICAgICAgICAgICAgICAgICAga2NzdHJpbmcgKyBwcm9wZXJsZW5ndGgsIGtjc3RyaW5nX2xlbik7CgogICAgICAgIFFVSVRGVU4ocnZhbCwgZW5jb2RlX2tleWNoYW5nZV9xdWl0KTsKCiAgICAgICAgKmtjc3RyaW5nX2xlbiA9IChwcm9wZXJsZW5ndGggKiAyKTsKCiAgICAgICAga2NzdHJpbmcgKz0gcHJvcGVybGVuZ3RoOwogICAgICAgIG5ieXRlcyA9IDA7CiAgICAgICAgd2hpbGUgKChuYnl0ZXMrKykgPCBwcm9wZXJsZW5ndGgpIHsKICAgICAgICAgICAgKmtjc3RyaW5nKysgXj0gKm5ld2tleSsrOwogICAgICAgIH0KICAgIH0KCiAgZW5jb2RlX2tleWNoYW5nZV9xdWl0OgogICAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgIG1lbXNldChrY3N0cmluZywgMCwgKmtjc3RyaW5nX2xlbik7CiAgICBTTk1QX0ZSRUUodG1wYnVmKTsKCiAgICByZXR1cm4gcnZhbDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGVuY29kZV9rZXljaGFuZ2UoKSAqLwoKI2Vsc2UKX0tFWVRPT0xTX05PVF9BVkFJTEFCTEUKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbnRlcm5hbCBvciBvcGVuc3NsICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGRlY29kZV9rZXljaGFuZ2UKICoKICogUGFyYW1ldGVyczoKICoJKmhhc2h0eXBlCU1JQiBPSUQgb2YgdGhlIGhhc2ggdHJhbnNmb3JtIHRvIHVzZS4KICoJIGhhc2h0eXBlX2xlbglMZW5ndGggb2YgdGhlIGhhc2ggdHJhbnNmb3JtIE1JQiBPSUQuCiAqCSpvbGRrZXkJCU9sZCBrZXkgdGhhdCBpcyB1c2VkIHRvIGVuY29kZSB0aGUgbmV3IGtleS4KICoJIG9sZGtleV9sZW4JTGVuZ3RoIG9mIG9sZGtleSBpbiBieXRlcy4KICoJKmtjc3RyaW5nCUVuY29kZWQgS2V5U3RyaW5nIGJ1ZmZlciBjb250YWluaW5nIHRoZSBuZXcga2V5LgogKgkga2NzdHJpbmdfbGVuCUxlbmd0aCBvZiBrY3N0cmluZyBpbiBieXRlcy4KICoJKm5ld2tleQkJQnVmZmVyIHRvIGhvbGQgdGhlIGV4dHJhY3RlZCBuZXcga2V5LgogKgkqbmV3a2V5X2xlbglMZW5ndGggb2YgbmV3a2V5IGluIGJ5dGVzLgogKiAgICAgIAogKiBSZXR1cm5zOgogKglTTk1QRVJSX1NVQ0NFU1MJCQlTdWNjZXNzLgogKglTTk1QRVJSX0dFTkVSUgkJCUFsbCBlcnJvcnMuCiAqCiAqCiAqIERlY29kZXMgYSBzdHJpbmcgb2YgYml0cyBlbmNvZGVkIGFjY29yZGluZyB0byB0aGUgS2V5Q2hhbmdlIFRDIGRlc2NyaWJlZAogKiBpbiBSRkMgMjI3NCwgU2VjdGlvbiA1LiAgVGhlIG5ldyBrZXkgaXMgZXh0cmFjdGVkIGZyb20gKmtjc3RyaW5nIHdpdGgKICogdGhlIGFpZCBvZiB0aGUgb2xkIGtleS4KICoKICogVXBvbiBzdWNjZXNzZnVsIHJldHVybiwgKm5ld2tleV9sZW4gY29udGFpbnMgdGhlIGxlbmd0aCBvZiB0aGUgbmV3IGtleS4KICoKICoKICogQVNTVU1FUwlPbGQga2V5IGlzIGV4YWN0bHkgMS8yIHRoZSBsZW5ndGggb2YgdGhlIEtleUNoYW5nZSBidWZmZXIsCiAqCQlhbHRob3VnaCB0aGlzIGxlbmd0aCBtYXkgYmUgbGVzcyB0aGFuIHRoZSBoYXNoIHRyYW5zZm9ybQogKgkJb3V0cHV0LiAgVGh1cyB0aGUgbmV3IGtleSBsZW5ndGggd2lsbCBiZSBlcXVhbCB0byB0aGUgb2xkCiAqCQlrZXkgbGVuZ3RoLgogKi8KLyoKICogWFhYOiAgaWYgdGhlIG5ld2tleSBpcyBub3QgbG9uZyBlbm91Z2gsIGl0IHNob3VsZCBiZSBmcmVlZCBhbmQgcmVtYWxsb2NlZCAKICovCmludApkZWNvZGVfa2V5Y2hhbmdlKGNvbnN0IG9pZCAqIGhhc2h0eXBlLCB1X2ludCBoYXNodHlwZV9sZW4sCiAgICAgICAgICAgICAgICAgdV9jaGFyICogb2xka2V5LCBzaXplX3Qgb2xka2V5X2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBrY3N0cmluZywgc2l6ZV90IGtjc3RyaW5nX2xlbiwKICAgICAgICAgICAgICAgICB1X2NoYXIgKiBuZXdrZXksIHNpemVfdCAqIG5ld2tleV9sZW4pCiNpZiBkZWZpbmVkKE5FVFNOTVBfVVNFX09QRU5TU0wpIHx8IGRlZmluZWQoTkVUU05NUF9VU0VfSU5URVJOQUxfTUQ1KSB8fCBkZWZpbmVkKE5FVFNOTVBfVVNFX1BLQ1MxMSkgfHwgZGVmaW5lZChORVRTTk1QX1VTRV9JTlRFUk5BTF9DUllQVE8pCnsKICAgIGludCAgICAgICAgICAgICBydmFsID0gU05NUEVSUl9TVUNDRVNTOwogICAgc2l6ZV90ICAgICAgICAgIHByb3Blcmxlbmd0aCA9IDA7CiAgICBpbnQgICAgICAgICAgICAgaXByb3Blcmxlbmd0aCA9IDA7CiAgICB1X2ludCAgICAgICAgICAgbmJ5dGVzID0gMDsKCiAgICB1X2NoYXIgICAgICAgICAqYnVmcCwgdG1wX2J1ZltTTk1QX01BWEJVRl07CiAgICBzaXplX3QgICAgICAgICAgdG1wX2J1Zl9sZW4gPSBTTk1QX01BWEJVRjsKICAgIHVfY2hhciAgICAgICAgICp0bXBidWYgPSBOVUxMOwoKCgogICAgLyoKICAgICAqIFNhbml0eSBjaGVjay4KICAgICAqLwogICAgaWYgKCFoYXNodHlwZSB8fCAhb2xka2V5IHx8ICFrY3N0cmluZyB8fCAhbmV3a2V5IHx8ICFuZXdrZXlfbGVuCiAgICAgICAgfHwgKG9sZGtleV9sZW4gPD0gMCkgfHwgKGtjc3RyaW5nX2xlbiA8PSAwKSB8fCAoKm5ld2tleV9sZW4gPD0gMCkKICAgICAgICB8fCAoaGFzaHR5cGVfbGVuICE9IFVTTV9MRU5HVEhfT0lEX1RSQU5TRk9STSkpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQoKCiAgICAvKgogICAgICogU2V0dXAgZm9yIHRoZSB0cmFuc2Zvcm0gdHlwZS4KICAgICAqLwogICAgaXByb3Blcmxlbmd0aCA9IHNjX2dldF9wcm9wZXJsZW5ndGgoaGFzaHR5cGUsIGhhc2h0eXBlX2xlbik7CiAgICBpZiAoaXByb3Blcmxlbmd0aCA9PSBTTk1QRVJSX0dFTkVSUikKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQpOwoKICAgIHByb3Blcmxlbmd0aCA9IChzaXplX3QpIGlwcm9wZXJsZW5ndGg7CgogICAgaWYgKCgob2xka2V5X2xlbiAqIDIpICE9IGtjc3RyaW5nX2xlbikgfHwgKCpuZXdrZXlfbGVuIDwgb2xka2V5X2xlbikpIHsKICAgICAgICBRVUlURlVOKFNOTVBFUlJfR0VORVJSLCBkZWNvZGVfa2V5Y2hhbmdlX3F1aXQpOwogICAgfQoKICAgIHByb3Blcmxlbmd0aCA9IG9sZGtleV9sZW47CiAgICAqbmV3a2V5X2xlbiA9IHByb3Blcmxlbmd0aDsKCiAgICAvKgogICAgICogVXNlIHRoZSBvbGQga2V5IGFuZCB0aGUgZ2l2ZW4gS2V5Q2hhbmdlIFRDIHN0cmluZyB0byByZWNvdmVyCiAgICAgKiB0aGUgbmV3IGtleToKICAgICAqICAgICAgLiBIYXNoIChvbGRrZXkgfCByYW5kb21fYnl0ZXMpIChpbnRvIG5ld2tleSksCiAgICAgKiAgICAgIC4gWE9SIGhhc2ggYW5kIGVuY29kZWQgKHNlY29uZCkgaGFsZiBvZiBrY3N0cmluZyAoaW50byBuZXdrZXkpLgogICAgICovCiAgICB0bXBidWYgPSAodV9jaGFyICopIG1hbGxvYyhwcm9wZXJsZW5ndGggKiAyKTsKICAgIGlmICh0bXBidWYpIHsKICAgICAgICBtZW1jcHkodG1wYnVmLCBvbGRrZXksIHByb3Blcmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHRtcGJ1ZiArIHByb3Blcmxlbmd0aCwga2NzdHJpbmcsIHByb3Blcmxlbmd0aCk7CgogICAgICAgIHJ2YWwgPSBzY19oYXNoKGhhc2h0eXBlLCBoYXNodHlwZV9sZW4sIHRtcGJ1ZiwgcHJvcGVybGVuZ3RoICogMiwKICAgICAgICAgICAgICAgICAgICAgICB0bXBfYnVmLCAmdG1wX2J1Zl9sZW4pOwogICAgICAgIFFVSVRGVU4ocnZhbCwgZGVjb2RlX2tleWNoYW5nZV9xdWl0KTsKCiAgICAgICAgbWVtY3B5KG5ld2tleSwgdG1wX2J1ZiwgcHJvcGVybGVuZ3RoKTsKICAgICAgICBidWZwID0ga2NzdHJpbmcgKyBwcm9wZXJsZW5ndGg7CiAgICAgICAgbmJ5dGVzID0gMDsKICAgICAgICB3aGlsZSAoKG5ieXRlcysrKSA8IHByb3Blcmxlbmd0aCkgewogICAgICAgICAgICAqbmV3a2V5KysgXj0gKmJ1ZnArKzsKICAgICAgICB9CiAgICB9CgogIGRlY29kZV9rZXljaGFuZ2VfcXVpdDoKICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIGlmIChuZXdrZXkpCiAgICAgICAgICAgIG1lbXNldChuZXdrZXksIDAsIHByb3Blcmxlbmd0aCk7CiAgICB9CiAgICBtZW1zZXQodG1wX2J1ZiwgMCwgU05NUF9NQVhCVUYpOwogICAgaWYgKHRtcGJ1ZiAhPSBOVUxMKQogICAgICAgIFNOTVBfRlJFRSh0bXBidWYpOwoKICAgIHJldHVybiBydmFsOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgZGVjb2RlX2tleWNoYW5nZSgpICovCgojZWxzZQpfS0VZVE9PTFNfTk9UX0FWQUlMQUJMRQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGludGVybmFsIG9yIG9wZW5zc2wgKi8K