LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtYWxsb2MuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9mY250bC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPHB3ZC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAic3RyaW5nMzIuaCIJCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2RlZmluZSBNQUtFX0RXT1JEKHgseSkgKChEV09SRClNQUtFTE9ORyh4LHkpKQoKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWAkJCSIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUCQkiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9DVVJSRU5UX1VTRVIJCSJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkUJCSJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkJIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQJIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgojZGVmaW5lIHN0cmR1cEEyVyh4KQlTVFJJTkczMl9EdXBBbnNpVG9VbmkoeCkKI2RlZmluZSBzdHJkdXBXKHgpCVNUUklORzMyX3N0cmR1cFcoeCkKI2RlZmluZSBzdHJjaHJXKGEsYykJU1RSSU5HMzJfbHN0cmNoclcoYSxjKQoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7CnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0xOwoKc3RhdGljIHZvaWQKYWRkX2hhbmRsZShIS0VZIGhrZXksTFBLRVlTVFJVQ1QgbHBrZXksUkVHU0FNIGFjY2Vzc21hc2spIHsKCWludAlpOwoKCWZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewoJCWlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKCQkJZHByaW50Zl9yZWcoc3RkZGViLCJhZGRfaGFuZGxlOlRyaWVkIHRvIGFkZCAlcCB0d2ljZSFcbiIsbHBrZXkpOwoJCX0KCQlpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkgewoJCQlkcHJpbnRmX3JlZyhzdGRkZWIsImFkZF9oYW5kbGU6VHJpZWQgdG8gYWRkICVseCB0d2ljZSFcbiIsKExPTkcpaGtleSk7CgkJfQoJfQoJb3BlbmhhbmRsZXM9eHJlYWxsb2MoCW9wZW5oYW5kbGVzLAoJCQkJc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzKzEpCgkJKTsKCW9wZW5oYW5kbGVzW2ldLmxwa2V5CT0gbHBrZXk7CglvcGVuaGFuZGxlc1tpXS5oa2V5CT0gaGtleTsKCW9wZW5oYW5kbGVzW2ldLmFjY2Vzc21hc2s9IGFjY2Vzc21hc2s7Cglucm9mb3BlbmhhbmRsZXMrKzsKfQoKc3RhdGljIExQS0VZU1RSVUNUCmdldF9oYW5kbGUoSEtFWSBoa2V5KSB7CglpbnQJaTsKCglmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspCgkJaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpCgkJCXJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKCWRwcmludGZfcmVnKHN0ZGRlYiwiZ2V0X2hhbmRsZTpEaWRuJ3QgZmluZCBoYW5kbGUgJWx4P1xuIiwoTE9ORyloa2V5KTsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZApyZW1vdmVfaGFuZGxlKEhLRVkgaGtleSkgewoJaW50CWk7CgoJZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQoJCWlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQoJCQlicmVhazsKCWlmIChpPT1ucm9mb3BlbmhhbmRsZXMpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsInJlbW92ZV9oYW5kbGU6RGlkbid0IGZpbmQgaGFuZGxlICUwOHg/XG4iLGhrZXkpOwoJCXJldHVybjsKCX0KCW1lbWNweSgJb3BlbmhhbmRsZXMraSwKCQlvcGVuaGFuZGxlcytpKzEsCgkJc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLWktMSkKCSk7CglvcGVuaGFuZGxlcz14cmVhbGxvYyhvcGVuaGFuZGxlcyxzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtMSkpOwoJbnJvZm9wZW5oYW5kbGVzLS07CglyZXR1cm47Cn0KCgovKiBkZWJ1ZyBmdW5jdGlvbiwgY29udmVydHMgYSB1bmljb2RlIGludG8gYSBzdGF0aWMgbWVtb3J5IGFyZWEgCiAqIChzdWIgZm9yIHVzaW5nIHR3byBzdGF0aWMgc3RyaW5ncywgaW4gY2FzZSB3ZSBuZWVkIHRoZW0gaW4gYSBzaW5nbGUgY2FsbCkKICovCkxQU1RSClcyQyhMUENXU1RSIHgsaW50IHN1YikgewoJc3RhdGljCUxQU1RSCXVuaWNvZGVkZWJ1Z1syXT17TlVMTCxOVUxMfTsKCWlmICh4PT1OVUxMKQoJCXJldHVybiAiPE5VTEw+IjsKCWlmIChzdWIhPTAgJiYgc3ViIT0xKQoJCXJldHVybiAiPFcyQzpiYWQgc3ViPiI7CglpZiAodW5pY29kZWRlYnVnW3N1Yl0pIEhlYXBGcmVlKCBTeXN0ZW1IZWFwLCAwLCB1bmljb2RlZGVidWdbc3ViXSApOwoJdW5pY29kZWRlYnVnW3N1Yl0gPSBIRUFQX3N0cmR1cFd0b0EoIFN5c3RlbUhlYXAsIDAsIHggKTsKCXJldHVybiB1bmljb2RlZGVidWdbc3ViXTsKfQoKc3RhdGljIExQS0VZU1RSVUNUCmxvb2t1cF9oa2V5KEhLRVkgaGtleSkgewoJc3dpdGNoIChoa2V5KSB7CgljYXNlIDB4MDAwMDAwMDA6CgljYXNlIDB4MDAwMDAwMDE6CgljYXNlIEhLRVlfQ0xBU1NFU19ST09UOgoJCXJldHVybiBrZXlfY2xhc3Nlc19yb290OwoJY2FzZSBIS0VZX0NVUlJFTlRfVVNFUjoKCQlyZXR1cm4ga2V5X2N1cnJlbnRfdXNlcjsKCWNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgoJCXJldHVybiBrZXlfbG9jYWxfbWFjaGluZTsKCWNhc2UgSEtFWV9VU0VSUzoKCQlyZXR1cm4ga2V5X3VzZXJzOwoJY2FzZSBIS0VZX1BFUkZPUk1BTkNFX0RBVEE6CgkJcmV0dXJuIGtleV9wZXJmb3JtYW5jZV9kYXRhOwoJY2FzZSBIS0VZX0RZTl9EQVRBOgoJCXJldHVybiBrZXlfZHluX2RhdGE7CgljYXNlIEhLRVlfQ1VSUkVOVF9DT05GSUc6CgkJcmV0dXJuIGtleV9jdXJyZW50X2NvbmZpZzsKCWRlZmF1bHQ6CgkJZHByaW50Zl9yZWcoc3RkZGViLCJsb29rdXBfaGtleSglbHgpLCBzcGVjaWFsIGtleSFcbiIsCgkJCShMT05HKWhrZXkKCQkpOwoJCXJldHVybiBnZXRfaGFuZGxlKGhrZXkpOwoJfQoJLypOT1RSRUFDSEVEKi8KfQoKLyogCiAqIHNwbGl0cyB0aGUgdW5pY29kZSBzdHJpbmcgJ3dwJyBpbnRvIGFuIGFycmF5IG9mIHN0cmluZ3MuCiAqIHRoZSBhcnJheSBpcyBhbGxvY2F0ZWQgYnkgdGhpcyBmdW5jdGlvbi4gCiAqIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cyB3aWxsIGJlIHN0b3JlZCBpbiAnd3BjJwogKiBGcmVlIHRoZSBhcnJheSB1c2luZyBGUkVFX0tFWV9QQVRICiAqLwpzdGF0aWMgdm9pZApzcGxpdF9rZXlwYXRoKExQQ1dTVFIgd3AsTFBXU1RSICoqd3B2LGludCAqd3BjKSB7CglpbnQJaSxqLGxlbjsKCUxQV1NUUgl3czsKCgl3cwk9IEhFQVBfc3RyZHVwVyggU3lzdGVtSGVhcCwgMCwgd3AgKTsKCSp3cGMJPSAxOwoJZm9yIChpPTA7d3NbaV07aSsrKSB7CgkJaWYgKHdzW2ldPT0nXFwnKSB7CgkJCXdzW2ldPTA7CgkJCSgqd3BjKSsrOwoJCX0KCX0KCWxlbgk9IGk7Cgkqd3B2CT0gKExQV1NUUiopSGVhcEFsbG9jKCBTeXN0ZW1IZWFwLCAwLCBzaXplb2YoTFBXU1RSKSooKndwYysyKSk7CgkoKndwdilbMF09IHdzOwoJagk9IDE7Cglmb3IgKGk9MTtpPGxlbjtpKyspCgkJaWYgKHdzW2ktMV09PTApCgkJCSgqd3B2KVtqKytdPXdzK2k7CgkoKndwdilbal09TlVMTDsKfQojZGVmaW5lIEZSRUVfS0VZX1BBVEggSGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwc1swXSk7SGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwcyk7CgovKgogKiBTaGVsbCBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIGtleXMuIAogKi8Kdm9pZCBTSEVMTF9TdGFydHVwUmVnaXN0cnkoKTsKdm9pZApTSEVMTF9Jbml0KCkgewoJc3RydWN0CXBhc3N3ZAkqcHdkOwoKCUhLRVkJY2xfcl9oa2V5LGNfdV9oa2V5OwojZGVmaW5lIEFERF9ST09UX0tFWSh4eCkgXAoJeHggPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7XAoJbWVtc2V0KHh4LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCXh4LT5rZXluYW1lPSBzdHJkdXBBMlcoIjxzaG91bGRfbm90X2FwcGVhcl9hbnl3aGVyZT4iKTsKCglBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwoJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiXFxTT0ZUV0FSRVxcQ2xhc3NlcyIsJmNsX3JfaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQlmcHJpbnRmKHN0ZGVyciwiY291bGRuJ3QgY3JlYXRlIEhLRVlfTE9DQUxfTUFDSElORVxcU09GVFdBUkVcXENsYXNzZXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIpOwoJCWV4aXQoMSk7Cgl9CglrZXlfY2xhc3Nlc19yb290ID0gbG9va3VwX2hrZXkoY2xfcl9oa2V5KTsKCglBRERfUk9PVF9LRVkoa2V5X3VzZXJzKTsKCiNpZiAwCgkvKiBGSVhNRTogbG9hZCBhbGwgdXNlcnMgYW5kIHRoZWlyIHJlc3AuIHB3ZC0+cHdfZGlyLy53aW5lL3VzZXIucmVnIAoJICoJICAobGF0ZXIsIHdoZW4gYSB3aW4zMiByZWdpc3RyeSBlZGl0aW5nIHRvb2wgYmVjb21lcyBhdmFpbC4pCgkgKi8KCXdoaWxlIChwd2Q9Z2V0cHdlbnQoKSkgewoJCWlmIChwd2QtPnB3X25hbWUgPT0gTlVMTCkKCQkJY29udGludWU7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KTsKCQlSZWdDbG9zZUtleShjX3VfaGtleSk7Cgl9CiNlbmRpZgoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QgJiYgcHdkLT5wd19uYW1lKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KTsKCQlrZXlfY3VycmVudF91c2VyID0gbG9va3VwX2hrZXkoY191X2hrZXkpOwoJfSBlbHNlIHsKCQlBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfdXNlcik7Cgl9CglBRERfUk9PVF9LRVkoa2V5X3BlcmZvcm1hbmNlX2RhdGEpOwoJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CglBRERfUk9PVF9LRVkoa2V5X2R5bl9kYXRhKTsKI3VuZGVmIEFERF9ST09UX0tFWQoJU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCk7Cn0KCgp2b2lkClNIRUxMX1N0YXJ0dXBSZWdpc3RyeSgpIHsKCUhLRVkJaGtleSx4aGtleT0wOwoJRklMRQkqRjsKCWNoYXIJYnVmWzIwMF0sY3B1YnVmWzIwMF07CgoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9EWU5fREFUQSwiXFxQZXJmU3RhdHNcXFN0YXREYXRhIiwmeGhrZXkpOwoJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJcXEhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtXFxDZW50cmFsUHJvY2Vzc29yIiwmaGtleSk7CiNpZmRlZiBsaW51eAoJRj1mb3BlbigiL3Byb2MvY3B1aW5mbyIsInIiKTsKCWlmIChGKSB7CgkJaW50CXByb2Nucj0tMSx4OwoJCXdoaWxlIChOVUxMIT1mZ2V0cyhidWYsMjAwLEYpKSB7CgkJCWlmIChzc2NhbmYoYnVmLCJwcm9jZXNzb3JcdDogJWQiLCZ4KSkgewoJCQkJc3ByaW50ZihidWYsIiVkIix4KTsKCQkJCWlmICh4aGtleSkKCQkJCQlSZWdDbG9zZUtleSh4aGtleSk7CgkJCQlwcm9jbnI9eDsKCQkJCVJlZ0NyZWF0ZUtleTE2KGhrZXksYnVmLCZ4aGtleSk7CgkJCX0KCQkJaWYgKHNzY2FuZihidWYsImNwdVx0XHQ6ICVzIixjcHVidWYpKSB7CgkJCQlzcHJpbnRmKGJ1ZiwiQ1BVICVzIixjcHVidWYpOwoJCQkJaWYgKHhoa2V5KQoJCQkJCVJlZ1NldFZhbHVlRXgzMkEoeGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSk7CgkJCX0KCQl9CgkJZmNsb3NlKEYpOwoJfQoJaWYgKHhoa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwojZWxzZQoJLyogRklYTUUgKi8KCVJlZ0NyZWF0ZUtleTE2KGhrZXksIjAiLCZ4aGtleSk7CglSZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiQ1BVIDM4NiIsc3RybGVuKCJDUFUgMzg2IikpOwojZW5kaWYKCVJlZ09wZW5LZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXgzMkEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93IE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCQkJCQkJCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJnhoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4MTYoeGhrZXksIkNvbXB1dGVyTmFtZSIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKzEpOwoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCX0KfQovKioqKioqKioqKioqKioqKioqKioqKioqIFNBVkUgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgUkVHSVNUUllfU0FWRV9WRVJTSU9OCTB4MDAwMDAwMDEKCi8qIFJlZ2lzdHJ5IHNhdmVmb3JtYXQ6CiAqIElmIHlvdSBjaGFuZ2UgaXQsIGluY3JlYXNlIGFib3ZlIG51bWJlciBieSAxLCB3aGljaCB3aWxsIGZsdXNoCiAqIG9sZCByZWdpc3RyeSBkYXRhYmFzZSBmaWxlcy4KICogCiAqIEdsb2JhbDoKICogCSJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiCiAqIAlzdWJrZXlzLi4uLgogKiBTdWJrZXlzOgogKiAJa2V5bmFtZQogKgkJdmFsdWVuYW1lPWxhc3Rtb2RpZmllZCx0eXBlLGRhdGEKICoJCS4uLgogKgkJc3Via2V5cwogKgkuLi4KICoga2V5bmFtZSx2YWx1ZW5hbWUsc3RyaW5nZGF0YToKICoJdGhlIHVzdWFsIGFzY2lpIGNoYXJhY3RlcnMgZnJvbSAweDAwLTB4ZmYgKHdlbGwsIG5vdCAweDAwKQogKglhbmQgXHVYWFhYIGFzIFVOSUNPREUgdmFsdWUgWFhYWCB3aXRoIFhYWFg+MHhmZgogKgkoICI9XFxcdCIgZXNjYXBlZCBpbiBcdVhYWFggZm9ybS4pCiAqIHR5cGUsbGFzdG1vZGlmaWVkOiAKICoJaW50CiAqIAogKiBGSVhNRTogZG9lc24ndCBzYXZlICdjbGFzcycgKHdoYXQgZG9lcyBpdCBtZWFuIGFueXdheT8pLCBub3IgZmxhZ3MuCiAqCiAqIFtIS0VZX0NVUlJFTlRfVVNFUlxcU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5XQogKiBTYXZlT25seVVwZGF0ZWRLZXlzPXllcwogKi8Kc3RhdGljIGludApfc2F2ZV9jaGVja190YWludGVkKExQS0VZU1RSVUNUIGxwa2V5KSB7CglpbnQJCXRhaW50ZWQ7CgoJaWYgKCFscGtleSkKCQlyZXR1cm4gMDsKCWlmIChscGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpCgkJdGFpbnRlZCA9IDE7CgllbHNlCgkJdGFpbnRlZCA9IDA7Cgl3aGlsZSAobHBrZXkpIHsKCQlpZiAoX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1YikpIHsKCQkJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkJdGFpbnRlZCA9IDE7CgkJfQoJCWxwa2V5CT0gbHBrZXktPm5leHQ7Cgl9CglyZXR1cm4gdGFpbnRlZDsKfQoKc3RhdGljIHZvaWQKX3NhdmVfVVNUUklORyhGSUxFICpGLExQV1NUUiB3c3RyLGludCBlc2NhcGVlcSkgewoJTFBXU1RSCXM7CglpbnQJZG9lc2NhcGU7CgoJaWYgKHdzdHI9PU5VTEwpCgkJcmV0dXJuOwoJcz13c3RyOwoJd2hpbGUgKCpzKSB7CgkJZG9lc2NhcGU9MDsKCQlpZiAoKnM+MHhmZikKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xuJykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmIChlc2NhcGVlcSAmJiAqcz09Jz0nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXFwnKQoJCQlmcHV0YygqcyxGKTsgLyogaWYgXFwgdGhhbiBwdXQgaXQgdHdpY2UuICovCgkJaWYgKGRvZXNjYXBlKQoJCQlmcHJpbnRmKEYsIlxcdSUwNHgiLCooKHVuc2lnbmVkIHNob3J0KilzKSk7CgkJZWxzZQoJCQlmcHV0YygqcyxGKTsKCQlzKys7Cgl9Cn0KCnN0YXRpYyBpbnQKX3NhdmVzdWJrZXkoRklMRSAqRixMUEtFWVNUUlVDVCBscGtleSxpbnQgbGV2ZWwsaW50IGFsbCkgewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpLHRhYnMsajsKCglscHhrZXkJPSBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoCSEobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVk9MQVRJTEUpICYmCgkJCShhbGwgfHwgKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpKQoJCSkgewoJCQlmb3IgKHRhYnM9bGV2ZWw7dGFicy0tOykKCQkJCWZwdXRjKCdcdCcsRik7CgkJCV9zYXZlX1VTVFJJTkcoRixscHhrZXktPmtleW5hbWUsMSk7CgkJCWZwdXRzKCJcbiIsRik7CgkJCWZvciAoaT0wO2k8bHB4a2V5LT5ucm9mdmFsdWVzO2krKykgewoJCQkJTFBLRVlWQUxVRQl2YWw9bHB4a2V5LT52YWx1ZXMraTsKCgkJCQlmb3IgKHRhYnM9bGV2ZWwrMTt0YWJzLS07KQoJCQkJCWZwdXRjKCdcdCcsRik7CgkJCQlfc2F2ZV9VU1RSSU5HKEYsdmFsLT5uYW1lLDApOwoJCQkJZnB1dGMoJz0nLEYpOwoJCQkJZnByaW50ZihGLCIlbGQsJWxkLCIsdmFsLT50eXBlLHZhbC0+bGFzdG1vZGlmaWVkKTsKCQkJCWlmICgoMTw8dmFsLT50eXBlKSAmIFVOSUNPTlZNQVNLKQoJCQkJCV9zYXZlX1VTVFJJTkcoRiwoTFBXU1RSKXZhbC0+ZGF0YSwwKTsKCQkJCWVsc2UKCQkJCQlmb3IgKGo9MDtqPHZhbC0+bGVuO2orKykKCQkJCQkJZnByaW50ZihGLCIlMDJ4IiwqKCh1bnNpZ25lZCBjaGFyKil2YWwtPmRhdGEraikpOwoJCQkJZnB1dHMoIlxuIixGKTsKCQkJfQoJCQkvKiBkZXNjZW5kIHJlY3Vyc2l2ZWx5ICovCgkJCWlmICghX3NhdmVzdWJrZXkoRixscHhrZXktPm5leHRzdWIsbGV2ZWwrMSxhbGwpKQoJCQkJcmV0dXJuIDA7CgkJfQoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglyZXR1cm4gMTsKfQoKc3RhdGljIGludApfc2F2ZXN1YnJlZyhGSUxFICpGLExQS0VZU1RSVUNUIGxwa2V5LGludCBhbGwpIHsKCWZwcmludGYoRiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkXG4iLFJFR0lTVFJZX1NBVkVfVkVSU0lPTik7Cglfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKTsKCXJldHVybiBfc2F2ZXN1YmtleShGLGxwa2V5LT5uZXh0c3ViLDAsYWxsKTsKfQoKc3RhdGljIEJPT0wzMgpfc2F2ZXJlZyhMUEtFWVNUUlVDVCBscGtleSxjaGFyICpmbixpbnQgYWxsKSB7CglGSUxFCSpGOwoKCUY9Zm9wZW4oZm4sInciKTsKCWlmIChGPT1OVUxMKSB7CgkJZnByaW50ZihzdGRkZWIsX19GSUxFX18iOl9zYXZlcmVnOkNvdWxkbid0IG9wZW4gJXMgZm9yIHdyaXRpbmc6ICVzXG4iLAoJCQlmbixzdHJlcnJvcihlcnJubykKCQkpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmICghX3NhdmVzdWJyZWcoRixscGtleSxhbGwpKSB7CgkJZmNsb3NlKEYpOwoJCXVubGluayhmbik7CgkJZnByaW50ZihzdGRkZWIsX19GSUxFX18iOl9zYXZlcmVnOkZhaWxlZCB0byBzYXZlIGtleXMsIHBlcmhhcHMgbm8gbW9yZSBkaXNrc3BhY2UgZm9yICVzP1xuIixmbik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJZmNsb3NlKEYpOwogICAgICAgIHJldHVybiBUUlVFOwp9Cgp2b2lkClNIRUxMX1NhdmVSZWdpc3RyeSgpIHsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJY2hhcglidWZbNF07CglIS0VZCWhrZXk7CglpbnQJYWxsOwoKCWFsbD0wOwoJaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJc3RyY3B5KGJ1ZiwieWVzIik7Cgl9IGVsc2UgewoJCURXT1JEIGxlbixqdW5rLHR5cGU7CgoJCWxlbj00OwoJCWlmICgJKEVSUk9SX1NVQ0NFU1MhPVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJYnVmLAoJCQkJJmxlbgoJCQkpKXx8ICh0eXBlIT1SRUdfU1opCgkJKQoJCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCWlmIChsc3RyY21waTMyQShidWYsInllcyIpKQoJCWFsbD0xOwoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpCiAgICAgICAgewogICAgICAgICAgICAgICAgY2hhciAqdG1wOwoKCQlmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKHB3ZC0+cHdfZGlyKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikgKyAyICk7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwoJCS8qIGNyZWF0ZSB0aGUgZGlyZWN0b3J5LiBkb24ndCBjYXJlIGFib3V0IGVycm9yY29kZXMuICovCgkJbWtkaXIoZm4sMDc1NSk7IC8qIGRyd3hyLXhyLXggKi8KCQlzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhrZXlfY3VycmVudF91c2VyLHRtcCxhbGwpKSB7CgkJCWlmICgtMT09cmVuYW1lKHRtcCxmbikpIHsKCQkJCXBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwoJCQkJdW5saW5rKHRtcCk7CgkJCX0KCQl9CgkJZnJlZSh0bXApOwoJCWZyZWUoZm4pOwoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgkJdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKCQlzdHJjcHkodG1wLGZuKTtzdHJjYXQodG1wLCIudG1wIik7CgkJaWYgKF9zYXZlcmVnKGtleV9sb2NhbF9tYWNoaW5lLHRtcCxhbGwpKSB7CgkJCWlmICgtMT09cmVuYW1lKHRtcCxmbikpIHsKCQkJCXBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwoJCQkJdW5saW5rKHRtcCk7CgkJCX0KCQl9CgkJZnJlZSh0bXApOwoJCWZyZWUoZm4pOwoJfSBlbHNlCgkJZnByaW50ZihzdGRlcnIsIlNIRUxMX1NhdmVSZWdpc3RyeTpmYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIExQS0VZU1RSVUNUCl9maW5kX29yX2FkZF9rZXkoTFBLRVlTVFJVQ1QgbHBrZXksTFBXU1RSIGtleW5hbWUpIHsKCUxQS0VZU1RSVUNUCWxweGtleSwqbHBscGtleTsKCglscGxwa2V5PSAmKGxwa2V5LT5uZXh0c3ViKTsKCWxweGtleQk9ICpscGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICghbHN0cmNtcDMyVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCnN0YXRpYyB2b2lkCl9maW5kX29yX2FkZF92YWx1ZSgKCUxQS0VZU1RSVUNUIGxwa2V5LExQV1NUUiBuYW1lLERXT1JEIHR5cGUsTFBCWVRFIGRhdGEsRFdPUkQgbGVuLAoJRFdPUkQgbGFzdG1vZGlmaWVkCikgewoJTFBLRVlWQUxVRQl2YWw9TlVMTDsKCWludAkJaTsKCglmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykgewoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJaWYgKG5hbWU9PU5VTEwpIHsKCQkJaWYgKHZhbC0+bmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJCX0gZWxzZSB7CgkJCWlmICgJdmFsLT5uYW1lIT1OVUxMICYmIAoJCQkJIWxzdHJjbXAzMlcodmFsLT5uYW1lLG5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJCX0KCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSB4cmVhbGxvYygKCQkJbHBrZXktPnZhbHVlcywKCQkJKCsrbHBrZXktPm5yb2Z2YWx1ZXMpKnNpemVvZihLRVlWQUxVRSkKCQkpOwoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJbWVtc2V0KHZhbCwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJCXZhbC0+bmFtZSA9IG5hbWU7Cgl9IGVsc2UgewoJCWlmIChuYW1lKQoJCQlmcmVlKG5hbWUpOwoJfQoJaWYgKHZhbC0+bGFzdG1vZGlmaWVkPGxhc3Rtb2RpZmllZCkgewoJCXZhbC0+bGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQl2YWwtPnR5cGUgPSB0eXBlOwoJCXZhbC0+bGVuICA9IGxlbjsKCQlpZiAodmFsLT5kYXRhKSAKCQkJZnJlZSh2YWwtPmRhdGEpOwoJCXZhbC0+ZGF0YSA9IGRhdGE7Cgl9IGVsc2UKCQlmcmVlKGRhdGEpOwp9CgoKLyogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgCl93aW5lX3JlYWRfbGluZShGSUxFICpGLGNoYXIgKipidWYsaW50ICpsZW4pIHsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCi8qIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKgpfd2luZV9yZWFkX1VTVFJJTkcoY2hhciAqYnVmLExQV1NUUiAqc3RyKSB7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoKnM9PSdcXCcpIHsKCQkJCSp3cys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlmcHJpbnRmKHN0ZGVyciwiX3dpbmVfcmVhZF9VU1RSSU5HOk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJZnByaW50ZihzdGRlcnIsIl93aW5lX3JlYWRfVVNUUklORzpzdHJhbmdlIGVzY2FwZSBzZXF1ZW5jZSAlcyBmb3VuZCBpbiB8JXN8XG4iLHhidWYsYnVmKTsKCQkJCXMrPTQ7CgkJCQkqd3MrKwk9KHVuc2lnbmVkIHNob3J0KXdjOwoJCQl9CgkJfQoJfQoJKndzCT0gMDsKCXdzCT0gKnN0cjsKCSpzdHIJPSBzdHJkdXBXKCpzdHIpOwoJZnJlZSh3cyk7CglyZXR1cm4gczsKfQoKc3RhdGljIGludApfd2luZV9sb2Fkc3Via2V5KAoJRklMRSAqRixMUEtFWVNUUlVDVCBscGtleSxpbnQgbGV2ZWwsY2hhciAqKmJ1ZixpbnQgKmJ1ZmxlbixpbnQgb3B0ZmxhZwopIHsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaTsKCWNoYXIJCSpzOwoJTFBXU1RSCQluYW1lOwoKCWxwa2V5LT5mbGFncyB8PSBvcHRmbGFnOwoKCS8qIGdvb2QuIHdlIGFscmVhZHkgZ290IGEgbGluZSBoZXJlIC4uLiBzbyBwYXJzZSBpdCAqLwoJbHB4a2V5CT0gTlVMTDsKCXdoaWxlICgxKSB7CgkJaT0wO3M9KmJ1ZjsKCQl3aGlsZSAoKnM9PSdcdCcpIHsKCQkJcysrOwoJCQlpKys7CgkJfQoJCWlmIChpPmxldmVsKSB7CgkJCWlmIChscHhrZXk9PU5VTEwpIHsKCQkJCWZwcmludGYoc3RkZXJyLCJfbG9hZF9zdWJrZXk6R290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CgkJCQlyZXR1cm4gMDsKCQkJfQoJCQlfd2luZV9sb2Fkc3Via2V5KEYsbHB4a2V5LGxldmVsKzEsYnVmLGJ1ZmxlbixvcHRmbGFnKTsKCQkJY29udGludWU7CgkJfQoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJcmV0dXJuIDE7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKCQkJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlmcHJpbnRmKHN0ZGVyciwiX3dpbmVfbG9hZF9zdWJrZXk6dW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCWZwcmludGYoc3RkZXJyLCJfd2luZV9sb2FkX3N1YmtleTogaGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCS8qIHNraXAgdGhlIDIgLCAqLwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlpZiAoKDE8PHR5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKCQkJCQlpZiAoZGF0YSkKCQkJCQkJbGVuID0gbHN0cmxlbjMyVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCQllbHNlCQoJCQkJCQlsZW4gPSAwOwoJCQkJfSBlbHNlIHsKCQkJCQlsZW49c3RybGVuKHMpLzI7CgkJCQkJZGF0YSA9IChMUEJZVEUpeG1hbGxvYyhsZW4rMSk7CgkJCQkJZm9yIChpPTA7aTxsZW47aSsrKSB7CgkJCQkJCWRhdGFbaV09MDsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV09KCpzLScwJyk8PDQ7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nYScpPDw0OwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ0EnKTw8NDsKCQkJCQkJcysrOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXXw9KnMtJzAnOwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ2EnOwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ0EnOwoJCQkJCQlzKys7CgkJCQkJfQoJCQkJfQoJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKGxwa2V5LG5hbWUsdHlwZSxkYXRhLGxlbixsYXN0bW9kaWZpZWQpOwoJCQl9CgkJfQoJCS8qIHJlYWQgdGhlIG5leHQgbGluZSAqLwoJCWlmICghX3dpbmVfcmVhZF9saW5lKEYsYnVmLGJ1ZmxlbikpCgkJCXJldHVybiAxOwoJfQoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQKX3dpbmVfbG9hZHN1YnJlZyhGSUxFICpGLExQS0VZU1RSVUNUIGxwa2V5LGludCBvcHRmbGFnKSB7CglpbnQJdmVyOwoJY2hhcgkqYnVmOwoJaW50CWJ1ZmxlbjsKCglidWY9eG1hbGxvYygxMCk7YnVmbGVuPTEwOwoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFzc2NhbmYoYnVmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiLCZ2ZXIpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKHZlciE9UkVHSVNUUllfU0FWRV9WRVJTSU9OKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLF9fRklMRV9fIjpfd2luZV9sb2Fkc3VicmVnOk9sZCBmb3JtYXQgKCVkKSByZWdpc3RyeSBmb3VuZCwgaWdub3JpbmcgaXQuIChidWYgd2FzICVzKS5cbiIsdmVyLGJ1Zik7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsbHBrZXksMCwmYnVmLCZidWZsZW4sb3B0ZmxhZykpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQKX3dpbmVfbG9hZHJlZyhMUEtFWVNUUlVDVCBscGtleSxjaGFyICpmbixpbnQgb3B0ZmxhZykgewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJyYiIpOwoJaWYgKEY9PU5VTEwpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsX19GSUxFX18iOkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLAoJCQlmbixzdHJlcnJvcihlcnJubykKCQkpOwoJCXJldHVybjsKCX0KCWlmICghX3dpbmVfbG9hZHN1YnJlZyhGLGxwa2V5LG9wdGZsYWcpKSB7CgkJZmNsb3NlKEYpOwoJCXVubGluayhmbik7CgkJcmV0dXJuOwoJfQoJZmNsb3NlKEYpOwp9CgpzdGF0aWMgdm9pZApfY29weV9yZWdpc3RyeShMUEtFWVNUUlVDVCBmcm9tLExQS0VZU1RSVUNUIHRvKSB7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWo7CglMUEtFWVZBTFVFCXZhbGZyb207CgoJZnJvbT1mcm9tLT5uZXh0c3ViOwoJd2hpbGUgKGZyb20pIHsKCQlscHhrZXkgPSBfZmluZF9vcl9hZGRfa2V5KHRvLHN0cmR1cFcoZnJvbS0+a2V5bmFtZSkpOwoKCQlmb3IgKGo9MDtqPGZyb20tPm5yb2Z2YWx1ZXM7aisrKSB7CgkJCUxQV1NUUgluYW1lOwoJCQlMUEJZVEUJZGF0YTsKCgkJCXZhbGZyb20gPSBmcm9tLT52YWx1ZXMrajsKCQkJbmFtZT12YWxmcm9tLT5uYW1lOwoJCQlpZiAobmFtZSkgbmFtZT1zdHJkdXBXKG5hbWUpOwoJCQlkYXRhPShMUEJZVEUpbWFsbG9jKHZhbGZyb20tPmxlbik7CgkJCW1lbWNweShkYXRhLHZhbGZyb20tPmRhdGEsdmFsZnJvbS0+bGVuKTsKCgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQl2YWxmcm9tLT50eXBlLAoJCQkJZGF0YSwKCQkJCXZhbGZyb20tPmxlbiwKCQkJCXZhbGZyb20tPmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlfY29weV9yZWdpc3RyeShmcm9tLGxweGtleSk7CgkJZnJvbSA9IGZyb20tPm5leHQ7Cgl9Cn0KCi8qIFdJTkRPV1MgOTUgUkVHSVNUUlkgTE9BREVSICovCi8qIAogKiBTdHJ1Y3R1cmUgb2YgYSB3aW45NSByZWdpc3RyeSBkYXRhYmFzZS4KICogbWFpbiBoZWFkZXI6CiAqIDAgOgkiQ1JFRyIJLSBtYWdpYwogKiA0IDoJRFdPUkQgdmVyc2lvbgogKiA4IDoJRFdPUkQgb2Zmc2V0X29mX1JHREJfcGFydAogKiAwQy4uMUY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqCiAqIDIwOiBSR0tOX3NlY3Rpb246CiAqICAgaGVhZGVyOgogKiAJMCA6CQkiUkdLTiIJLSBtYWdpYwogKiAJNC4uMHgxQjogCT8gKGZpbGwgaW4pCiAqICAgICAgMHgyMCAuLi4gb2Zmc2V0X29mX1JHREJfcGFydDogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlcwogKgogKiAgIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZToKICoJMDA6IERXT1JECS0gdW5rbm93bgogKgkwNDogRFdPUkQJLSB1bmtub3duCiAqCTA4OiBEV09SRAktIHVua25vd24sIGJ1dCB1c3VhbGx5IDB4RkZGRkZGRkYgb24gd2luOTUgc3lzdGVtcwogKgkwQzogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgUHJldmlvdXNMZXZlbCBLZXkuCiAqCTEwOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IFN1YmxldmVsIEtleS4KICoJMTQ6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgS2V5IChvbiBzYW1lIGxldmVsKS4KICogREtFUD4xODogV09SRAktIE5yLCBMb3cgU2lnbmlmaWNhbnQgcGFydC4KICoJMUE6IFdPUkQJLSBOciwgSGlnaCBTaWduaWZpY2FudCBwYXJ0LgogKgogKiBUaGUgZGlzayBhZGRyZXNzIGFsd2F5cyBwb2ludHMgdG8gdGhlIG5yIHBhcnQgb2YgdGhlIHByZXZpb3VzIGtleSBlbnRyeSAKICogb2YgdGhlIHJlZmVyZW5jZWQga2V5LiBEb24ndCBhc2sgbWUgd2h5LCBvciBldmVuIGlmIEkgZ290IHRoaXMgY29ycmVjdAogKiBmcm9tIHN0YXJpbmcgYXQgMWtnIG9mIGhleGR1bXBzLiAoREtFUCkKICoKICogVGhlIG51bWJlciBvZiB0aGUgZW50cnkgaXMgdGhlIGxvdyBieXRlIG9mIHRoZSBMb3cgU2lnbmlmaWNhbnQgUGFydCBvcmVkCiAqIHdpdGggMHgxMDAgKiAobG93IGJ5dGUgb2YgdGhlIEhpZ2ggU2lnbmlmaWNhbnQgcGFydCkKICogKEMgZXhwcmVzc2lvbiA6IG5yID0gKG5yTFMgJiAweEZGKSB8ICgobnJIUyAmMHhGRik8PDgpKQogKgogKiBUaGVyZSBhcmUgdHdvIG1pbm9yIGNvcnJlY3Rpb25zIHRvIHRoZSBwb3NpdGlvbiBvZiB0aGF0IHN0cnVjdHVyZS4KICogMS4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4MDE0IG9yIHh4eDAxOCBpdCB3aWxsIGJlIGFsaWduZWQgdG8geHh4MDFjIEFORCAKICogICAgdGhlIERLRSByZXJlYWQgZnJvbSB0aGVyZS4KICogMi4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4RkZ4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byAoeHh4KzEpMDAwLgogKiAoRklYTUU6IHNsaWdodGx5IGJldHRlciBleHBsYW5hdGlvbiBuZWVkZWQgaGVyZSkKICoKICogUkdEQl9zZWN0aW9uOgogKiAJMDA6CQkiUkdEQiIJLSBtYWdpYwogKgkwNDogRFdPUkQJb2Zmc2V0IHRvIG5leHQgUkdEQiBzZWN0aW9uIChwZXJoYXBzIFdPUkQpCiAqCTA4Li4uMUY6CT8KICoJMjAuLi4uLjoJZGlzayBrZXlzCiAqCiAqIGRpc2sga2V5OgogKiAJMDA6IAlEV09SRAluZXh0a2V5b2Zmc2V0CS0gb2Zmc2V0IHRvIHRoZSBuZXh0IGRpc2sga2V5IHN0cnVjdHVyZQogKgkwODogCVdPUkQJbnJMUwkJLSBsb3cgc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQTogCVdPUkQJbnJIUwkJLSBoaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEM6IAlEV09SRAlieXRlc3VzZWQJLSBieXRlcyB1c2VkIGluIHRoaXMgc3RydWN0dXJlLgogKgkxMDogCVdPUkQJbmFtZV9sZW4JLSBsZW5ndGggb2YgbmFtZSBpbiBieXRlcy4gd2l0aG91dCBcMAogKgkxMjogCVdPUkQJbnJfb2ZfdmFsdWVzCS0gbnVtYmVyIG9mIHZhbHVlcy4KICoJMTQ6IAljaGFyCW5hbWVbbmFtZV9sZW5dCS0gbmFtZSBzdHJpbmcuIE5vIFwwLgogKgkxNCtuYW1lX2xlbjogZGlzayB2YWx1ZXMKICoJbmV4dGtleW9mZnNldDogLi4uIG5leHQgZGlzayBrZXkKICoKICogZGlzayB2YWx1ZToKICoJMDA6CURXT1JECXR5cGUJCS0gdmFsdWUgdHlwZSAoaG1tLCBjb3VsZCBiZSBXT1JEIHRvbykKICoJMDQ6CURXT1JECQkJLSB1bmtub3duLCB1c3VhbGx5IDAKICoJMDg6CVdPUkQJbmFtZWxlbgkJLSBsZW5ndGggb2YgTmFtZS4gMCBtZWFucyBuYW1lPU5VTEwKICoJMEM6CVdPUkQJZGF0YWxlbgkJLSBsZW5ndGggb2YgRGF0YS4KICoJMTA6CWNoYXIJbmFtZVtuYW1lbGVuXQktIG5hbWUsIG5vIFwwCiAqCTEwK25hbWVsZW46IEJZVEUJZGF0YVtkYXRhbGVuXSAtIGRhdGEsIHdpdGhvdXQgXDAgaWYgc3RyaW5nCiAqCTEwK25hbWVsZW4rZGF0YWxlbjogbmV4dCB2YWx1ZXMgb3IgZGlzayBrZXkKICoKICogRGlzayBrZXlzIGFyZSBsYXllZCBvdXQgZmxhdCAuLi4gQnV0LCBzb21ldGltZXMsIG5yTFMgYW5kIG5ySFMgYXJlIGJvdGgKICogMHhGRkZGLCB3aGljaCBtZWFucyBza2lwcGluZyBvdmVyIG5leHRrZXlvZmZzZXQgYnl0ZXMgKGluY2x1ZGluZyB0aGlzCiAqIHN0cnVjdHVyZSkgYW5kIHJlYWRpbmcgYW5vdGhlciBSR0RCX3NlY3Rpb24uCiAqIHJlcGVhdCB1bnRpbCBlbmQgb2YgZmlsZS4KICoKICogRklYTUU6IHRoaXMgZGVzY3JpcHRpb24gbmVlZHMgc29tZSBzZXJpb3VzIGhlbHAsIHllcy4KICovCgpzdHJ1Y3QJX3c5NWtleXZhbHVlIHsKCXVuc2lnbmVkIGxvbmcJCXR5cGU7Cgl1bnNpZ25lZCBzaG9ydAkJZGF0YWxlbjsKCWNoYXIJCQkqbmFtZTsKCXVuc2lnbmVkIGNoYXIJCSpkYXRhOwoJdW5zaWduZWQgbG9uZwkJeDE7CglpbnQJCQlsYXN0bW9kaWZpZWQ7Cn07CgpzdHJ1Y3QgCV93OTVrZXkgewoJY2hhcgkJCSpuYW1lOwoJaW50CQkJbnJvZnZhbHM7CglzdHJ1Y3QJX3c5NWtleXZhbHVlCSp2YWx1ZXM7Cgl1bnNpZ25lZCBsb25nCQlka2VhZGRyOwoJdW5zaWduZWQgbG9uZyAJCXgxOwoJdW5zaWduZWQgbG9uZyAJCXgyOwoJdW5zaWduZWQgbG9uZyAJCXgzOwoJdW5zaWduZWQgbG9uZyAJCXh4MTsKCXN0cnVjdCBfdzk1a2V5CQkqcHJldmx2bDsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dHN1YjsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dDsKfTsKCi8qIGZhc3QgbG9va3VwIHRhYmxlIGRrZWFkZHItPm5yICovCnN0cnVjdAlfdzk1bnIyZGEgewoJdW5zaWduZWQgbG9uZwkJZGtlYWRkcjsKCXVuc2lnbmVkIGxvbmcJCW5yOwp9OwoKCnN0YXRpYyB2b2lkCl93OTVfd2Fsa190cmVlKExQS0VZU1RSVUNUIGxwa2V5LHN0cnVjdCBfdzk1a2V5ICprZXkpIHsKCWludAkJaTsKCUxQS0VZU1RSVUNUCWxweGtleTsKCUxQV1NUUgkJbmFtZTsKCgl3aGlsZSAoa2V5KSB7CgkJaWYgKGtleS0+bmFtZSA9PSBOVUxMKSB7CgkJCWZwcmludGYoc3RkZXJyLCJfdzk1X3dhbGtfdHJlZTpQbGVhc2UgcmVwb3J0OiBrZXkgd2l0aCBka2VhZGRyICVseCBub3QgbG9hZGVkLCBza2lwcGluZyBoaWVyYXJjaHlcbiIsCgkJCQlrZXktPmRrZWFkZHIKCQkJKTsKCQkJcmV0dXJuOwoJCX0KCQlscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxzdHJkdXBBMlcoa2V5LT5uYW1lKSk7CgoJCWlmIChrZXktPm5yb2Z2YWxzPDApIHsKCQkJLyogc2hvdWxkbid0IGhhcHBlbiAqLwoJCQlmcHJpbnRmKHN0ZGVyciwia2V5ICVzIGFscmVhZHkgcHJvY2Vzc2VkIVxuIixrZXktPm5hbWUpOwoJCQlrZXkgPSBrZXktPm5leHQ7CgkJCWNvbnRpbnVlOwoJCX0KCQlmb3IgKGk9MDtpPGtleS0+bnJvZnZhbHM7aSsrKSB7CgkJCUxQQllURQlkYXRhOwoJCQlpbnQJbGVuOwoKCQkJbmFtZSA9IHN0cmR1cEEyVyhrZXktPnZhbHVlc1tpXS5uYW1lKTsKCQkJaWYgKCEqbmFtZSkgbmFtZSA9IE5VTEw7CgkJCWZyZWUoa2V5LT52YWx1ZXNbaV0ubmFtZSk7CgoJCQlsZW4JPSBrZXktPnZhbHVlc1tpXS5kYXRhbGVuOwoJCQlkYXRhCT0ga2V5LT52YWx1ZXNbaV0uZGF0YTsKCQkJaWYgKCgxPDxrZXktPnZhbHVlc1tpXS50eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQlkYXRhID0gKEJZVEUqKXN0cmR1cEEyVyhkYXRhKTsKCQkJCWxlbiAgPSBsc3RybGVuMzJXKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJZnJlZShrZXktPnZhbHVlc1tpXS5kYXRhKTsKCQkJfQoJCQlfZmluZF9vcl9hZGRfdmFsdWUoCgkJCQlscHhrZXksCgkJCQluYW1lLAoJCQkJa2V5LT52YWx1ZXNbaV0udHlwZSwKCQkJCWRhdGEsCgkJCQlsZW4sCgkJCQlrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQKCQkJKTsKCQl9CgkJaWYgKGtleS0+dmFsdWVzKSB7CgkJCWZyZWUoa2V5LT52YWx1ZXMpOwoJCQlrZXktPnZhbHVlcyA9IE5VTEw7CgkJfQoJCWtleS0+bnJvZnZhbHM9LWtleS0+bnJvZnZhbHMtMTsKCQlfdzk1X3dhbGtfdHJlZShscHhrZXksa2V5LT5uZXh0c3ViKTsKCQlrZXk9a2V5LT5uZXh0OwoJfQp9CgovKiBzbWFsbCBoZWxwZXIgZnVuY3Rpb24gdG8gYWRqdXN0IGFkZHJlc3Mgb2Zmc2V0IChka2VhZGRycykgKi8Kc3RhdGljIHVuc2lnbmVkIGxvbmcKX3c5NV9hZGpfZGEodW5zaWduZWQgbG9uZyBka2VhZGRyKSB7CglpZiAoKGRrZWFkZHImMHhGRkYpPDB4MDE4KSB7CgkJaW50CWRpZmY7CgoJCWRpZmY9MHgxQy0oZGtlYWRkciYweEZGRik7CgkJcmV0dXJuIGRrZWFkZHIrZGlmZjsKCX0KCWlmICgoKGRrZWFkZHIrMHgxQykmMHhGRkYpPDB4MUMpIHsKCQkvKiByZWFkanVzdCB0byAweDAwMCwKCQkgKiBidXQgT05MWSBpZiB3ZSBhcmUgPjB4MTAwMCBhbHJlYWR5CgkJICovCgkJaWYgKGRrZWFkZHIgJiB+MHhGRkYpCgkJCXJldHVybiBka2VhZGRyICYgfjB4RkZGOwoJfQoJcmV0dXJuIGRrZWFkZHI7Cn0KCnN0YXRpYyBpbnQKX3c5NWRrZWNvbXAoc3RydWN0IF93OTVucjJkYSAqYSxzdHJ1Y3QgX3c5NW5yMmRhICpiKXtyZXR1cm4gYS0+ZGtlYWRkci1iLT5ka2VhZGRyO30KCnN0YXRpYyBzdHJ1Y3QgX3c5NWtleSoKX3c5NWRrZWxvb2t1cCh1bnNpZ25lZCBsb25nIGRrZWFkZHIsaW50IG4sc3RydWN0IF93OTVucjJkYSAqbnIyZGEsc3RydWN0IF93OTVrZXkgKmtleXMpIHsKCWludAlpLG9mZjsKCglpZiAoZGtlYWRkciA9PSAweEZGRkZGRkZGKQoJCXJldHVybiBOVUxMOwoJaWYgKGRrZWFkZHI8MHgyMCkKCQlyZXR1cm4gTlVMTDsKCWRrZWFkZHI9X3c5NV9hZGpfZGEoZGtlYWRkcisweDFjKTsKCW9mZiA9IChka2VhZGRyLTB4M2MpLzB4MWM7Cglmb3IgKGk9MDtpPG47aSsrKQoJCWlmIChucjJkYVsoaStvZmYpJW5dLmRrZWFkZHIgPT0gZGtlYWRkcikKCQkJcmV0dXJuIGtleXMrbnIyZGFbKGkrb2ZmKSVuXS5ucjsKCS8qIDB4M0MgaGFwcGVucyBvZnRlbiwganVzdCByZXBvcnQgdW51c3VhbCB2YWx1ZXMgKi8KCWlmIChka2VhZGRyIT0weDNjKQoJCWRwcmludGZfcmVnKHN0ZGRlYiwic2VhcmNoIGhhc24ndCBmb3VuZCBka2VhZGRyICVseD9cbiIsZGtlYWRkcik7CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQKX3c5NV9sb2FkcmVnKGNoYXIqIGZuLExQS0VZU1RSVUNUIGxwa2V5KSB7CgkvKiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmUgKFJHS04gcGFydCkgKi8KCXN0cnVjdAlka2UgewoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIGxvbmcJCXgyOwoJCXVuc2lnbmVkIGxvbmcJCXgzOy8qdXN1YWxseSAweEZGRkZGRkZGICovCgkJdW5zaWduZWQgbG9uZwkJcHJldmx2bDsKCQl1bnNpZ25lZCBsb25nCQluZXh0c3ViOwoJCXVuc2lnbmVkIGxvbmcJCW5leHQ7CgkJdW5zaWduZWQgc2hvcnQJCW5yTFM7CgkJdW5zaWduZWQgc2hvcnQJCW5yTVM7Cgl9OwoJLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSAqLwoJc3RydWN0CWRraCB7CgkJdW5zaWduZWQgbG9uZwkJbmV4dGtleW9mZjsgCgkJdW5zaWduZWQgc2hvcnQJCW5yTFM7CgkJdW5zaWduZWQgc2hvcnQJCW5yTVM7CgkJdW5zaWduZWQgbG9uZwkJYnl0ZXN1c2VkOwoJCXVuc2lnbmVkIHNob3J0CQlrZXluYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWx1ZXM7CgkJdW5zaWduZWQgbG9uZwkJeHgxOwoJCS8qIGtleW5hbWUgKi8KCQkvKiBkaXNrIGtleSB2YWx1ZXMgb3Igbm90aGluZyAqLwoJfTsKCS8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSAqLwoJc3RydWN0CWRrdiB7CgkJdW5zaWduZWQgbG9uZwkJdHlwZTsKCQl1bnNpZ25lZCBsb25nCQl4MTsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsbmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsZGF0YWxlbjsKCQkvKiB2YWxuYW1lLCB2YWxkYXRhICovCgl9OwoJc3RydWN0CV93OTVucjJkYSAJKm5yMmRhOwoKCUhGSUxFMzIJCWhmZDsKCWludAkJbGFzdG1vZGlmaWVkOwoJY2hhcgkJbWFnaWNbNV07Cgl1bnNpZ25lZCBsb25nCW5yLHBvcyxpLHdoZXJlLHZlcnNpb24scmdkYnNlY3Rpb24sZW5kLG9mZl9uZXh0X3JnZGI7CglzdHJ1Y3QJX3c5NWtleQkqa2V5czsKCWludAkJbnJvZmRrZXM7Cgl1bnNpZ25lZCBjaGFyCSpkYXRhLCpjdXJkYXRhLCpuZXh0cmdkYjsKCU9GU1RSVUNUCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmZGluZm87CgoJZHByaW50Zl9yZWcoc3RkZGViLCJMb2FkaW5nIFdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlICclcydcbiIsZm4pOwoJaGZkPU9wZW5GaWxlMzIoZm4sJm9mcyxPRl9SRUFEKTsKCWlmIChoZmQ9PUhGSUxFX0VSUk9SMzIpCgkJcmV0dXJuOwoJbWFnaWNbNF09MDsKCWlmICg0IT1fbHJlYWQzMihoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiQ1JFRyIpKSB7CgkJZnByaW50ZihzdGRkZWIsIiVzIGlzIG5vdCBhIHc5NSByZWdpc3RyeS5cbiIsZm4pOwoJCXJldHVybjsKCX0KCWlmICg0IT1fbHJlYWQzMihoZmQsJnZlcnNpb24sNCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCwmcmdkYnNlY3Rpb24sNCkpCgkJcmV0dXJuOwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4MjAsU0VFS19TRVQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQzMihoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiUkdLTiIpKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVzXG4iLG1hZ2ljKTsKCQlyZXR1cm47Cgl9CgoJLyogU1RFUCAxOiBLZXlsaW5rIHN0cnVjdHVyZXMgKi8KCWlmICgtMT09X2xsc2VlazMyKGhmZCwweDQwLFNFRUtfU0VUKSkKCQlyZXR1cm47Cgl3aGVyZQk9IDB4NDA7CgllbmQJPSByZ2Ric2VjdGlvbjsKCglucm9mZGtlcyA9IChlbmQtd2hlcmUpL3NpemVvZihzdHJ1Y3QgZGtlKSsxMDA7CglkYXRhID0gKGNoYXIqKXhtYWxsb2MoZW5kLXdoZXJlKTsKCWlmICgoZW5kLXdoZXJlKSE9X2xyZWFkMzIoaGZkLGRhdGEsZW5kLXdoZXJlKSkKCQlyZXR1cm47CgljdXJkYXRhID0gZGF0YTsKCglrZXlzID0gKHN0cnVjdCBfdzk1a2V5Kil4bWFsbG9jKG5yb2Zka2VzICogc2l6ZW9mKHN0cnVjdCBfdzk1a2V5KSk7CgltZW1zZXQoa2V5cywnXDAnLG5yb2Zka2VzKnNpemVvZihzdHJ1Y3QgX3c5NWtleSkpOwoJbnIyZGE9IChzdHJ1Y3QgX3c5NW5yMmRhKil4bWFsbG9jKG5yb2Zka2VzICogc2l6ZW9mKHN0cnVjdCBfdzk1bnIyZGEpKTsKCW1lbXNldChucjJkYSwnXDAnLG5yb2Zka2VzKnNpemVvZihzdHJ1Y3QgX3c5NW5yMmRhKSk7CgoJZm9yIChpPTA7aTxucm9mZGtlcztpKyspIHsKCQlzdHJ1Y3QJZGtlCWRrZTsKCQl1bnNpZ25lZCBsb25nIAlka2VhZGRyOwoKCQlwb3M9Y3VyZGF0YS1kYXRhKzB4NDA7CgkJbWVtY3B5KCZka2UsY3VyZGF0YSxzaXplb2YoZGtlKSk7CgkJY3VyZGF0YSs9c2l6ZW9mKGRrZSk7CgkJbnIgPSBka2UubnJMUyArIChka2UubnJNUzw8OCk7CgkJZGtlYWRkcj1wb3MtNDsKCQlpZiAoKGRrZWFkZHImMHhGRkYpPDB4MDE4KSB7CgkJCWludAlkaWZmOwoKCQkJZGlmZj0weDFDLShka2VhZGRyJjB4RkZGKTsKCQkJZGtlYWRkcis9ZGlmZjsKCQkJY3VyZGF0YSs9ZGlmZi1zaXplb2YoZGtlKTsKCQkJbWVtY3B5KCZka2UsY3VyZGF0YSxzaXplb2YoZGtlKSk7CgkJCW5yID0gZGtlLm5yTFMgKyAoZGtlLm5yTVM8PDgpOwoJCQljdXJkYXRhKz1zaXplb2YoZGtlKTsKCQl9CgkJaWYgKCgoZGtlYWRkcisweDFDKSYweEZGRik8MHgxQykgewoJCQkvKiByZWFkanVzdCB0byAweDAwMCwKCQkJICogYnV0IE9OTFkgaWYgd2UgYXJlID4weDEwMDAgYWxyZWFkeQoJCQkgKi8KCQkJaWYgKGRrZWFkZHIgJiB+MHhGRkYpCgkJCQlka2VhZGRyID0gZGtlYWRkciAmIH4weEZGRjsKCQl9CgkJaWYgKG5yPm5yb2Zka2VzKSB7CgkJCS8qIDB4RkZGRkZGRkYgaGFwcGVucyBvZnRlbiwganVzdCByZXBvcnQgdW51c3VhbCB2YWx1ZXMgKi8KCQkJaWYgKG5yIT0weEZGRkZGRkZGKQoJCQkJZHByaW50Zl9yZWcoc3RkZGViLCJuciAlbGQgZXhjZWVkcyBucm9mZGtlcyAlZCwgc2tpcHBpbmcuXG4iLG5yLG5yb2Zka2VzKTsKCQkJY29udGludWU7CgkJfQoJCWlmIChrZXlzW25yXS5ka2VhZGRyKSB7CgkJCWludAl4OwoKCQkJZm9yICh4PXNpemVvZihka2UpO3gtLTspCgkJCQlpZiAoKChjaGFyKikmZGtlKVt4XSkKCQkJCQlicmVhazsKCQkJaWYgKHg9PS0xKQoJCQkJYnJlYWs7IC8qIGZpbmlzaGVkIHJlYWRpbmcgaWYgd2UgZ290IG9ubHkgMCAqLwoJCQlpZiAobnIpIHsKCQkJCWlmICgJKGRrZS5uZXh0IT0obG9uZylrZXlzW25yXS5uZXh0KQl8fAoJCQkJCShka2UubmV4dHN1YiE9KGxvbmcpa2V5c1tucl0ubmV4dHN1YikJfHwKCQkJCQkoZGtlLnByZXZsdmwhPShsb25nKWtleXNbbnJdLnByZXZsdmwpIAoJCQkJKQoJCQkJCWRwcmludGZfcmVnKHN0ZGRlYiwia2V5IGRvdWJsZWQ/IG5yPSVsZCxrZXktPmRrZWFkZHI9JWx4LGRrZWFkZHI9JWx4XG4iLG5yLGtleXNbbnJdLmRrZWFkZHIsZGtlYWRkcik7CgkJCX0KCQkJY29udGludWU7CgkJfQoJCW5yMmRhW2ldLm5yCSA9IG5yOwoJCW5yMmRhW2ldLmRrZWFkZHIgPSBka2VhZGRyOwoKCQlrZXlzW25yXS5ka2VhZGRyID0gZGtlYWRkcjsKCQlrZXlzW25yXS54MSA9IGRrZS54MTsKCQlrZXlzW25yXS54MiA9IGRrZS54MjsKCQlrZXlzW25yXS54MyA9IGRrZS54MzsKCQlrZXlzW25yXS5wcmV2bHZsPSAoc3RydWN0IF93OTVrZXkqKWRrZS5wcmV2bHZsOwoJCWtleXNbbnJdLm5leHRzdWI9IChzdHJ1Y3QgX3c5NWtleSopZGtlLm5leHRzdWI7CgkJa2V5c1tucl0ubmV4dCAJPSAoc3RydWN0IF93OTVrZXkqKWRrZS5uZXh0OwoJfQoJZnJlZShkYXRhKTsKCglxc29ydChucjJkYSxucm9mZGtlcyxzaXplb2YobnIyZGFbMF0pLAogICAgICAgICAgICAgIChpbnQoKikoY29uc3Qgdm9pZCAqLGNvbnN0IHZvaWQqKSlfdzk1ZGtlY29tcCk7CgoJLyogU1RFUCAyOiBrZXlkYXRhICYgdmFsdWVzICovCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmZCwmaGZkaW5mbykpCgkJcmV0dXJuOwoJZW5kID0gaGZkaW5mby5uRmlsZVNpemVMb3c7CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmZGluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKCWlmICgtMT09X2xsc2VlazMyKGhmZCxyZ2Ric2VjdGlvbixTRUVLX1NFVCkpCgkJcmV0dXJuOwoJZGF0YSA9IChjaGFyKil4bWFsbG9jKGVuZC1yZ2Ric2VjdGlvbik7CglpZiAoKGVuZC1yZ2Ric2VjdGlvbikhPV9scmVhZDMyKGhmZCxkYXRhLGVuZC1yZ2Ric2VjdGlvbikpCgkJcmV0dXJuOwoJX2xjbG9zZTMyKGhmZCk7CgljdXJkYXRhID0gZGF0YTsKCW1lbWNweShtYWdpYyxjdXJkYXRhLDQpOwoJbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCW5leHRyZ2RiID0gY3VyZGF0YStvZmZfbmV4dF9yZ2RiOwoJaWYgKHN0cmNtcChtYWdpYywiUkdEQiIpKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJ0aGlyZCBJRkYgaGVhZGVyIG5vdCBSR0RCLCBidXQgJXNcbiIsbWFnaWMpOwoJCXJldHVybjsKCX0KCWN1cmRhdGE9ZGF0YSsweDIwOwoJd2hpbGUgKDEpIHsKCQlzdHJ1Y3QJZGtoIGRraDsKCQlpbnQJYnl0ZXNyZWFkOwoJCXN0cnVjdAlfdzk1a2V5CSprZXkseGtleTsKCgkJYnl0ZXNyZWFkID0gMDsKCQlpZiAoY3VyZGF0YT49bmV4dHJnZGIpIHsKCQkJY3VyZGF0YSA9IG5leHRyZ2RiOwoJCQlpZiAoIXN0cm5jbXAoY3VyZGF0YSwiUkdEQiIsNCkpIHsKCQkJCW1lbWNweSgmb2ZmX25leHRfcmdkYixjdXJkYXRhKzQsNCk7CgkJCQluZXh0cmdkYiA9IGN1cmRhdGErb2ZmX25leHRfcmdkYjsKCQkJCWN1cmRhdGErPTB4MjA7CgkJCX0gZWxzZSB7CgkJCQlkcHJpbnRmX3JlZyhzdGRkZWIsImF0IGVuZCBvZiBSR0RCIHNlY3Rpb24sIGJ1dCBubyBuZXh0IGhlYWRlciAoJXggb2YgJWx4KS4gQnJlYWtpbmcuXG4iLGN1cmRhdGEtZGF0YSxlbmQtcmdkYnNlY3Rpb24pOwoJCQkJYnJlYWs7CgkJCX0KCQl9CiNkZWZpbmUgWFJFQUQod2hlcmV0byxsZW4pIFwKCWlmICgoY3VyZGF0YS1kYXRhK2xlbik8ZW5kKSB7XAoJCW1lbWNweSh3aGVyZXRvLGN1cmRhdGEsbGVuKTtcCgkJY3VyZGF0YSs9bGVuO1wKCQlieXRlc3JlYWQrPWxlbjtcCgl9CgoJCVhSRUFEKCZka2gsc2l6ZW9mKGRraCkpOwoJCW5yID0gZGtoLm5yTFMgKyAoZGtoLm5yTVM8PDgpOwoJCWlmICgobnI+bnJvZmRrZXMpIHx8IChka2gubnJMUyA9PSAweEZGRkYpKSB7CgkJCWlmIChka2gubnJMUyA9PSAweEZGRkYpIHsKCQkJCS8qIHNraXAgb3ZlciBrZXkgdXNpbmcgbmV4dGtleW9mZiAqLwogCQkJCWN1cmRhdGErPWRraC5uZXh0a2V5b2ZmLXNpemVvZihzdHJ1Y3QgZGtoKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiaGF2ZW4ndCBmb3VuZCBuciAlbGQuXG4iLG5yKTsKCQkJa2V5ID0gJnhrZXk7CgkJCW1lbXNldChrZXksJ1wwJyxzaXplb2YoeGtleSkpOwoJCX0gZWxzZSB7CgkJCWtleSA9IGtleXMrbnI7CgkJCWlmICgha2V5LT5ka2VhZGRyKQoJCQkJZHByaW50Zl9yZWcoc3RkZGViLCJrZXkgd2l0aCBucj0lbGQgaGFzIG5vIGRrZWFkZHI/XG4iLG5yKTsKCQl9CgkJa2V5LT5ucm9mdmFscwk9IGRraC52YWx1ZXM7CgkJa2V5LT5uYW1lCT0gKGNoYXIqKXhtYWxsb2MoZGtoLmtleW5hbWVsZW4rMSk7CgkJa2V5LT54eDEJPSBka2gueHgxOwoJCVhSRUFEKGtleS0+bmFtZSxka2gua2V5bmFtZWxlbik7CgkJa2V5LT5uYW1lW2RraC5rZXluYW1lbGVuXT0wOwoJCWlmIChrZXktPm5yb2Z2YWxzKSB7CgkJCWtleS0+dmFsdWVzID0gKHN0cnVjdCBfdzk1a2V5dmFsdWUqKXhtYWxsb2MoCgkJCQlzaXplb2Yoc3RydWN0IF93OTVrZXl2YWx1ZSkqa2V5LT5ucm9mdmFscwoJCQkpOwoJCQlmb3IgKGk9MDtpPGtleS0+bnJvZnZhbHM7aSsrKSB7CgkJCQlzdHJ1Y3QJZGt2CWRrdjsKCgkJCQlYUkVBRCgmZGt2LHNpemVvZihka3YpKTsKCQkJCWtleS0+dmFsdWVzW2ldLnR5cGUgPSBka3YudHlwZTsKCQkJCWtleS0+dmFsdWVzW2ldLm5hbWUgPSAoY2hhciopeG1hbGxvYygKCQkJCQlka3YudmFsbmFtZWxlbisxCgkJCQkpOwoJCQkJa2V5LT52YWx1ZXNbaV0uZGF0YWxlbiA9IGRrdi52YWxkYXRhbGVuOwoJCQkJa2V5LT52YWx1ZXNbaV0uZGF0YSA9ICh1bnNpZ25lZCBjaGFyKil4bWFsbG9jKAoJCQkJCWRrdi52YWxkYXRhbGVuKzEKCQkJCSk7CgkJCQlrZXktPnZhbHVlc1tpXS54MSAgID0gZGt2LngxOwoJCQkJWFJFQUQoa2V5LT52YWx1ZXNbaV0ubmFtZSxka3YudmFsbmFtZWxlbik7CgkJCQlYUkVBRChrZXktPnZhbHVlc1tpXS5kYXRhLGRrdi52YWxkYXRhbGVuKTsKCQkJCWtleS0+dmFsdWVzW2ldLmRhdGFbZGt2LnZhbGRhdGFsZW5dPTA7CgkJCQlrZXktPnZhbHVlc1tpXS5uYW1lW2Rrdi52YWxuYW1lbGVuXT0wOwoJCQkJa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQkJfQoJCX0KCQlpZiAoYnl0ZXNyZWFkICE9IGRraC5uZXh0a2V5b2ZmKSB7CgkJCWlmIChka2guYnl0ZXN1c2VkICE9IGJ5dGVzcmVhZCkKCQkJCWRwcmludGZfcmVnKHN0ZGRlYiwKCQkJCQkicmVhZCBoYXMgZGlmZmVyZW5jZSBpbiByZWFkIGJ5dGVzICglZCkgYW5kIG5leHRvZmZzZXQgKCVsZCkgKGJ5dGVzdXNlZD0lbGQpXG4iLGJ5dGVzcmVhZCxka2gubmV4dGtleW9mZiwKCQkJCQlka2guYnl0ZXN1c2VkCgkJCQkpOwoJCQljdXJkYXRhICs9IGRraC5uZXh0a2V5b2ZmLWJ5dGVzcmVhZDsKCQl9CgkJa2V5LT5wcmV2bHZsCT0gX3c5NWRrZWxvb2t1cCgobG9uZylrZXktPnByZXZsdmwsbnJvZmRrZXMsbnIyZGEsa2V5cyk7CgkJa2V5LT5uZXh0c3ViCT0gX3c5NWRrZWxvb2t1cCgobG9uZylrZXktPm5leHRzdWIsbnJvZmRrZXMsbnIyZGEsa2V5cyk7CgkJa2V5LT5uZXh0CT0gX3c5NWRrZWxvb2t1cCgobG9uZylrZXktPm5leHQsbnJvZmRrZXMsbnIyZGEsa2V5cyk7CgkJaWYgKCFieXRlc3JlYWQpCgkJCWJyZWFrOwoJfQoJZnJlZShkYXRhKTsKCV93OTVfd2Fsa190cmVlKGxwa2V5LGtleXMpOwoJZnJlZShrZXlzKTsKfQoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUxQS0VZU1RSVUNUCWxwa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CglMUEtFWVNUUlVDVAkJeGxwa2V5ID0gTlVMTDsKCUxQV1NUUgkJCW5hbWUsdmFsdWU7CglzdGF0aWMgY2hhcgkJdGFpbFs0MDBdOwoKCXdoaWxlIChpZHghPTApIHsKCQlkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKCQlpZiAoZGlyLT5rZXlfaWR4KSB7CgkJCWtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCgkJCW1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CgkJCXRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CgkJCS8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUgCgkJCSAqIHRvcGxldmVsIHN1YmRpcmVjdG9yeSBiZWxvbmcgdG8gXFNPRlRXQVJFXENsYXNzZXMKCQkJICovCgkJCWlmICghbGV2ZWwgJiYgIWxzdHJjbXAzMkEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQkJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJCQkJY29udGludWU7CgkJCX0KCQkJbmFtZT1TVFJJTkczMl9EdXBBbnNpVG9VbmkodGFpbCk7CgoJCQl4bHBrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCgkJCS8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwoJCQlpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CgkJCQlpZiAoZGlyLT52YWx1ZV9pZHgpIHsKCQkJCQl2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CgkJCQkJbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKCQkJCQl0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwoJCQkJCXZhbHVlPVNUUklORzMyX0R1cEFuc2lUb1VuaSh0YWlsKTsKCQkJCQlfZmluZF9vcl9hZGRfdmFsdWUoeGxwa2V5LE5VTEwsUkVHX1NaLChMUEJZVEUpdmFsdWUsbHN0cmxlbjMyVyh2YWx1ZSkqMisyLGxhc3Rtb2RpZmllZCk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlkcHJpbnRmX3JlZyhzdGRkZWIsIl9fdzMxX2R1bXB0cmVlOnN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CgkJfQoJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCx4bHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJfQp9Cgp2b2lkCl93MzFfbG9hZHJlZygpIHsKCUhGSUxFMzIJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCUhLRVkJCQloa2V5OwoJTFBLRVlTVFJVQ1QJCWxwa2V5OwoKCWhmID0gT3BlbkZpbGUzMigicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKCWlmIChoZj09SEZJTEVfRVJST1IzMikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQzMihoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJfdzMxX2xvYWRyZWc6cmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJfdzMxX2xvYWRyZWc6cmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCWxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CgkvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCgl0YWIgPSB4bWFsbG9jKGxlbik7CglpZiAobGVuIT1fbHJlYWQzMihoZix0YWIsbGVuKSkgewoJCWRwcmludGZfcmVnKHN0ZGVyciwiX3czMV9sb2FkcmVnOmNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAoJCWZyZWUodGFiKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCgkvKiByZWFkIHRleHQgKi8KCXR4dCA9IHhtYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CglpZiAoLTE9PV9sbHNlZWszMihoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJZHByaW50Zl9yZWcoc3RkZXJyLCJfdzMxX2xvYWRyZWc6Y291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQzMihoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKCQlkcHJpbnRmX3JlZyhzdGRlcnIsIl93MzFfbG9hZHJlZzp0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CgkJZHByaW50Zl9yZWcoc3RkZXJyLCJfdzMxX2xvYWRyZWc6R2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcU09GVFdBUkVcXENsYXNzZXMiLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykKCQlyZXR1cm47CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZTMyKGhmKTsKCXJldHVybjsKfQoKdm9pZApTSEVMTF9Mb2FkUmVnaXN0cnkoKSB7CgljaGFyCSpmbjsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCgoJaWYgKGtleV9jbGFzc2VzX3Jvb3Q9PU5VTEwpCgkJU0hFTExfSW5pdCgpOwoKCS8qIExvYWQgd2luZG93cyAzLjEgZW50cmllcyAqLwoJX3czMV9sb2FkcmVnKCk7CgkvKiBMb2FkIHdpbmRvd3MgOTUgZW50cmllcyAqLwoJX3c5NV9sb2FkcmVnKCJDOlxcc3lzdGVtLjFzdCIsCWtleV9sb2NhbF9tYWNoaW5lKTsKCV93OTVfbG9hZHJlZygic3lzdGVtLmRhdCIsCWtleV9sb2NhbF9tYWNoaW5lKTsKCV93OTVfbG9hZHJlZygidXNlci5kYXQiLAlrZXlfdXNlcnMpOwoKCS8qIHRoZSBnbG9iYWwgdXNlciBkZWZhdWx0IGlzIGxvYWRlZCB1bmRlciBIS0VZX1VTRVJTXFwuRGVmYXVsdCAqLwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7Cglfd2luZV9sb2FkcmVnKGxwa2V5LFNBVkVfVVNFUlNfREVGQVVMVCwwKTsKCgkvKiBIS0VZX1VTRVJTXFwuRGVmYXVsdCBpcyBjb3BpZWQgdG8gSEtFWV9DVVJSRU5UX1VTRVIgKi8KCV9jb3B5X3JlZ2lzdHJ5KGxwa2V5LGtleV9jdXJyZW50X3VzZXIpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzICovCglfd2luZV9sb2FkcmVnKGtleV9sb2NhbF9tYWNoaW5lLFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxULDApOwoKCS8qIGxvYWQgdGhlIHVzZXIgc2F2ZWQgcmVnaXN0cmllcyAqLwoKCS8qIEZJWE1FOiB1c2UgZ2V0ZW52KCJIT01FIikgb3IgZ2V0cHd1aWQoZ2V0dWlkKCkpLT5wd19kaXIgPz8gKi8KCglwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJaWYgKHB3ZCE9TlVMTCAmJiBwd2QtPnB3X2RpciE9TlVMTCkgewoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCV93aW5lX2xvYWRyZWcoa2V5X2N1cnJlbnRfdXNlcixmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgkJX3dpbmVfbG9hZHJlZyhrZXlfbG9jYWxfbWFjaGluZSxmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJfSBlbHNlCgkJZnByaW50ZihzdGRlcnIsIlNIRUxMX0xvYWRSZWdpc3RyeTpmYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7CglpZiAoRVJST1JfU1VDQ0VTUz09UmVnQ3JlYXRlS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSkgewoJCURXT1JECWp1bmssdHlwZSxsZW47CgkJY2hhcglkYXRhWzVdOwoKCQlsZW49NDsKCQlpZiAoKAlSZWdRdWVyeVZhbHVlRXgzMkEoCgkJCQloa2V5LAoJCQkJVkFMX1NBVkVVUERBVEVELAoJCQkJJmp1bmssCgkJCQkmdHlwZSwKCQkJCWRhdGEsCgkJCQkmbGVuCgkJCSkhPUVSUk9SX1NVQ0NFU1MpIHx8CgkJCXR5cGUgIT0gUkVHX1NaCgkJKQoJCQlSZWdTZXRWYWx1ZUV4MzJBKGhrZXksVkFMX1NBVkVVUERBVEVELDAsUkVHX1NaLCJ5ZXMiLDQpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBBUEkgRlVOQ1RJT05TICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogT3BlbiBLZXlzLgogKgogKiBBbGwgZnVuY3Rpb25zIGFyZSBzdHVicyB0byBSZWdPcGVuS2V5RXgzMlcgd2hlcmUgYWxsIHRoZQogKiBtYWdpYyBoYXBwZW5zLiAKICoKICogRklYTUU6IHNlY3VyaXR5LG9wdGlvbnMsZGVzaXJlZGFjY2VzcywuLi4KICoKICogQ2FsbHBhdGg6CiAqIFJlZ09wZW5LZXkxNiAtPiBSZWdPcGVuS2V5MzJBIC0+IFJlZ09wZW5LZXlFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ09wZW5LZXkzMlcgICAtPiBSZWdPcGVuS2V5RXgzMlcgCiAqLwoKLyogUmVnT3BlbktleUV4VwkJW0FEVkFQSTMyLjE1MF0gKi8KRFdPUkQgUmVnT3BlbktleUV4MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdSZXNlcnZlZCwKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBIS0VZCXJldGtleQopIHsKCUxQS0VZU1RSVUNUCWxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5RXgzMlcoJWx4LCVzLCVsZCwlbHgsJXApXG4iLAoJCShMT05HKWhrZXksVzJDKGxwc3pTdWJLZXksMCksZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleQoJKTsKCglscE5leHRLZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBOZXh0S2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CgkJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoJCSpyZXRrZXk9Y3VycmVudGhhbmRsZTsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgkJfQoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CgkqcmV0a2V5CT0gY3VycmVudGhhbmRsZTsKCUZSRUVfS0VZX1BBVEg7CglyZXR1cm4JU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnT3BlbktleVcJCQlbQURWQVBJMzIuMTUxXSAqLwpEV09SRCBSZWdPcGVuS2V5MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnT3BlbktleTMyVyglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksVzJDKGxwc3pTdWJLZXksMCkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ09wZW5LZXlFeDMyVyhoa2V5LGxwc3pTdWJLZXksMCxLRVlfQUxMX0FDQ0VTUyxyZXRrZXkpOwp9CgoKLyogUmVnT3BlbktleUV4QQkJW0FEVkFQSTMyLjE0OV0gKi8KRFdPUkQgUmVnT3BlbktleUV4MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1Jlc2VydmVkLAoJUkVHU0FNCXNhbURlc2lyZWQsCglMUEhLRVkJcmV0a2V5CikgewoJTFBXU1RSCWxwc3pTdWJLZXlXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnT3BlbktleUV4MzJBKCVseCwlcywlbGQsJWx4LCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXksZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleQoJKTsKCWlmIChscHN6U3ViS2V5KQoJCWxwc3pTdWJLZXlXPXN0cmR1cEEyVyhscHN6U3ViS2V5KTsKCWVsc2UKCQlscHN6U3ViS2V5Vz1OVUxMOwoJcmV0PVJlZ09wZW5LZXlFeDMyVyhoa2V5LGxwc3pTdWJLZXlXLGR3UmVzZXJ2ZWQsc2FtRGVzaXJlZCxyZXRrZXkpOwoJaWYgKGxwc3pTdWJLZXlXKQoJCWZyZWUobHBzelN1YktleVcpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnT3BlbktleUEJCQlbQURWQVBJMzIuMTQ4XSAqLwpEV09SRCBSZWdPcGVuS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5MzJBKCVseCwlcywlcClcbiIsCgkJKExPTkcpaGtleSxscHN6U3ViS2V5LHJldGtleQoJKTsKCXJldHVybglSZWdPcGVuS2V5RXgzMkEoaGtleSxscHN6U3ViS2V5LDAsS0VZX0FMTF9BQ0NFU1MscmV0a2V5KTsKfQoKLyogUmVnT3BlbktleQkJCVtTSEVMTC4xXSBbS0VSTkVMLjIxN10gKi8KRFdPUkQgUmVnT3BlbktleTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5MTYoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ09wZW5LZXkzMkEoaGtleSxscHN6U3ViS2V5LHJldGtleSk7Cn0KCi8qIAogKiBDcmVhdGUga2V5cwogKiAKICogQWxsIHRob3NlIGZ1bmN0aW9ucyBjb252ZXJ0IHRoZWlyIHJlc3BlY3RpdmUgCiAqIGFyZ3VtZW50cyBhbmQgY2FsbCBSZWdDcmVhdGVLZXlFeFcgYXQgdGhlIGVuZC4KICoKICogRklYTUU6IG5vIHNlY3VyaXR5LG5vIGFjY2VzcyBhdHRyaWIsbm8gb3B0aW9uaGFuZGxpbmcgeWV0LgogKgogKiBDYWxscGF0aDoKICogUmVnQ3JlYXRlS2V5MTYgLT4gUmVnQ3JlYXRlS2V5MzJBIC0+IFJlZ0NyZWF0ZUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0NyZWF0ZUtleTMyVyAgIC0+IFJlZ0NyZWF0ZUtleUV4MzJXCiAqLwoKLyogUmVnQ3JlYXRlS2V5RXhXCQlbQURWQVBJMzIuMTMxXSAqLwpEV09SRCBSZWdDcmVhdGVLZXlFeDMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCURXT1JECWR3UmVzZXJ2ZWQsCglMUFdTVFIJbHBzekNsYXNzLAoJRFdPUkQJZmR3T3B0aW9ucywKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywKCUxQSEtFWQlyZXRrZXksCglMUERXT1JECWxwRGlzcG9zCikgewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKLypGSVhNRTogaGFuZGxlIHNlY3VyaXR5L2FjY2Vzcy93aGF0ZXZlciAqLwoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDcmVhdGVLZXlFeDMyVyglbHgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLAoJCShMT05HKWhrZXksCgkJVzJDKGxwc3pTdWJLZXksMCksCgkJZHdSZXNlcnZlZCwKCQlXMkMobHBzekNsYXNzLDEpLAoJCWZkd09wdGlvbnMsCgkJc2FtRGVzaXJlZCwKCQlscFNlY0F0dHJpYnMsCgkJcmV0a2V5LAoJCWxwRGlzcG9zCgkpOwoKCWxwTmV4dEtleQk9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscE5leHRLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKCQlhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwoJCWxwTmV4dEtleS0+ZmxhZ3N8PVJFR19PUFRJT05fVEFJTlRFRDsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KQoJCQlicmVhazsKCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJaWYgKGxweGtleSkgewoJCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwoJCWlmIChscERpc3BvcykKCQkJKmxwRGlzcG9zCT0gUkVHX09QRU5FRF9FWElTVElOR19LRVk7CgkJRlJFRV9LRVlfUEFUSDsKCQlyZXR1cm4JU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCS8qIGdvb2QuIG5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlyZXR1cm4gU0hFTExfRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJKCpscGxwUHJldktleSktPmtleW5hbWUJPSBzdHJkdXBXKHdwc1tpXSk7CgkJKCpscGxwUHJldktleSktPm5leHQJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0c3ViCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+dmFsdWVzCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bnJvZnZhbHVlcyA9IDA7CgkJKCpscGxwUHJldktleSktPmZsYWdzIAk9IFJFR19PUFRJT05fVEFJTlRFRDsKCQlpZiAobHBzekNsYXNzKQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgkJZWxzZQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBOVUxMOwoJCWxwTmV4dEtleQk9ICpscGxwUHJldktleTsKCQlpKys7Cgl9CglhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgoJLypGSVhNRTogZmxhZyBoYW5kbGluZyBjb3JyZWN0PyAqLwoJbHBOZXh0S2V5LT5mbGFncz0gZmR3T3B0aW9ucyB8UkVHX09QVElPTl9UQUlOVEVEOwoJaWYgKGxwc3pDbGFzcykKCQlscE5leHRLZXktPmNsYXNzID0gc3RyZHVwVyhscHN6Q2xhc3MpOwoJZWxzZQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBOVUxMOwoJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwoJaWYgKGxwRGlzcG9zKQoJCSpscERpc3Bvcwk9IFJFR19DUkVBVEVEX05FV19LRVk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0NyZWF0ZUtleVcJCVtBRFZBUEkzMi4xMzJdICovCkRXT1JEIFJlZ0NyZWF0ZUtleTMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCUxQSEtFWQlyZXRrZXkKKSB7CglEV09SRAlqdW5rLHJldDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0NyZWF0ZUtleTMyVyglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksVzJDKGxwc3pTdWJLZXksMCkscmV0a2V5CgkpOwoJcmV0PVJlZ0NyZWF0ZUtleUV4MzJXKAoJCWhrZXksCQkvKiBrZXkgaGFuZGxlICovCgkJbHBzelN1YktleSwJLyogc3Via2V5IG5hbWUgKi8KCQkwLAkJLyogcmVzZXJ2ZWQgPSAwICovCgkJTlVMTCwJCS8qIGxwc3pDbGFzcz8gRklYTUU6ID8gKi8KCQlSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwJLyogb3B0aW9ucyAqLwoJCUtFWV9BTExfQUNDRVNTLAkvKiBkZXNpcmVkIGFjY2VzcyBhdHRyaWJzICovCgkJTlVMTCwJCS8qIGxwc2VjdXJpdHkgYXR0cmlidXRlcyAqLwoJCXJldGtleSwJCS8qIGxwcmV0a2V5ICovCgkJJmp1bmsJCS8qIGRpc3Bvc2l0aW9uIHZhbHVlICovCgkpOwoJcmV0dXJuCXJldDsKfQoKLyogUmVnQ3JlYXRlS2V5RXhBCQlbQURWQVBJMzIuMTMwXSAqLwpEV09SRCBSZWdDcmVhdGVLZXlFeDMyQSgKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdSZXNlcnZlZCwKCUxQU1RSCWxwc3pDbGFzcywKCURXT1JECWZkd09wdGlvbnMsCglSRUdTQU0Jc2FtRGVzaXJlZCwKCUxQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsCglMUEhLRVkJcmV0a2V5LAoJTFBEV09SRAlscERpc3BvcwopIHsKCUxQV1NUUglscHN6U3ViS2V5VyxscHN6Q2xhc3NXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5RXgzMkEoJWx4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIiwKCQkoTE9ORyloa2V5LAoJCWxwc3pTdWJLZXksCgkJZHdSZXNlcnZlZCwKCQlscHN6Q2xhc3MsCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleSkKCQlscHN6U3ViS2V5Vz1zdHJkdXBBMlcobHBzelN1YktleSk7CgllbHNlCgkJbHBzelN1YktleVc9TlVMTDsKCWlmIChscHN6Q2xhc3MpCgkJbHBzekNsYXNzVz1zdHJkdXBBMlcobHBzekNsYXNzKTsKCWVsc2UKCQlscHN6Q2xhc3NXPU5VTEw7CglyZXQ9UmVnQ3JlYXRlS2V5RXgzMlcoCgkJaGtleSwKCQlscHN6U3ViS2V5VywKCQlkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleVcpCgkJZnJlZShscHN6U3ViS2V5Vyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnQ3JlYXRlS2V5QQkJW0FEVkFQSTMyLjEyOV0gKi8KRFdPUkQgUmVnQ3JlYXRlS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJRFdPUkQJanVuazsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0NyZWF0ZUtleTMyQSglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxyZXRrZXkKCSk7CglyZXR1cm4JUmVnQ3JlYXRlS2V5RXgzMkEoCgkJaGtleSwJCS8qIGtleSBoYW5kbGUgKi8KCQlscHN6U3ViS2V5LAkvKiBzdWJrZXkgbmFtZSAqLwoJCTAsCQkvKiByZXNlcnZlZCA9IDAgKi8KCQlOVUxMLAkJLyogbHBzekNsYXNzPyBGSVhNRTogPyAqLwoJCVJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLC8qIG9wdGlvbnMgKi8KCQlLRVlfQUxMX0FDQ0VTUywJLyogZGVzaXJlZCBhY2Nlc3MgYXR0cmlicyAqLwoJCU5VTEwsCQkvKiBscHNlY3VyaXR5IGF0dHJpYnV0ZXMgKi8KCQlyZXRrZXksCQkvKiBscHJldGtleSAqLwoJCSZqdW5rCQkvKiBkaXNwb3NpdGlvbiB2YWx1ZSAqLwoJKTsKfQoKLyogUmVnQ3JlYXRlS2V5CQkJW1NIRUxMLjJdIFtLRVJORUwuMjE4XSAqLwpEV09SRCBSZWdDcmVhdGVLZXkxNigKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5MTYoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ0NyZWF0ZUtleTMyQShoa2V5LGxwc3pTdWJLZXkscmV0a2V5KTsKfQoKLyogCiAqIFF1ZXJ5IFZhbHVlIEZ1bmN0aW9ucwogKiBXaW4zMiBkaWZmZXJzIGJldHdlZW4ga2V5bmFtZXMgYW5kIHZhbHVlbmFtZXMuIAogKiBtdWx0aXBsZSB2YWx1ZXMgbWF5IGJlbG9uZyB0byBvbmUga2V5LCB0aGUgc3BlY2lhbCB2YWx1ZQogKiB3aXRoIG5hbWUgTlVMTCBpcyB0aGUgZGVmYXVsdCB2YWx1ZSB1c2VkIGJ5IHRoZSB3aW4zMQogKiBjb21wYXQgZnVuY3Rpb25zLgogKgogKiBDYWxscGF0aDoKICogUmVnUXVlcnlWYWx1ZTE2IC0+IFJlZ1F1ZXJ5VmFsdWUzMkEgLT4gUmVnUXVlcnlWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdRdWVyeVZhbHVlMzJXIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyVwogKi8KCi8qIFJlZ1F1ZXJ5VmFsdWVFeFcJCVtBRFZBUEkzMi4xNThdICovCkRXT1JEIFJlZ1F1ZXJ5VmFsdWVFeDMyVygKCUhLRVkJaGtleSwKCUxQV1NUUglscHN6VmFsdWVOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlRXgzMlcoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwKCQloa2V5LFcyQyhscHN6VmFsdWVOYW1lLDApLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoKCWxwa2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXAzMlcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJaWYgKGxwc3pWYWx1ZU5hbWU9PU5VTEwpIHsKCQkJaWYgKGxwYkRhdGEpIHsKCQkJCSooV0NIQVIqKWxwYkRhdGEgPSAwOwoJCQkJKmxwY2JEYXRhCT0gMjsKCQkJfQoJCQlpZiAobHBkd1R5cGUpCgkJCQkqbHBkd1R5cGUJPSBSRUdfU1o7CgkJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJCX0KCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOy8qRklYTUU6IGNvcnJlY3QgcmV0dXJuPyAqLwoJfQoJaWYgKGxwZHdUeXBlKQoJCSpscGR3VHlwZQk9IGxwa2V5LT52YWx1ZXNbaV0udHlwZTsKCWlmIChscGJEYXRhPT1OVUxMKSB7CgkJaWYgKGxwY2JEYXRhPT1OVUxMKQoJCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCQkqbHBjYkRhdGEJPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCWlmICgqbHBjYkRhdGE8bHBrZXktPnZhbHVlc1tpXS5sZW4pIHsKCQkqKFdDSEFSKilscGJEYXRhCgkJCT0gMDsKCQkqbHBjYkRhdGEJPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJfQoJbWVtY3B5KGxwYkRhdGEsbHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwa2V5LT52YWx1ZXNbaV0ubGVuKTsKCSpscGNiRGF0YQk9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ1F1ZXJ5VmFsdWVXCQlbQURWQVBJMzIuMTU5XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlMzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pTdWJLZXksCglMUFdTVFIJbHBzekRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJSEtFWQl4aGtleTsKCURXT1JECXJldCxscGR3VHlwZTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWUzMlcoJXgsJXMsJXAsJWxkKVxuLT4iLAoJCWhrZXksVzJDKGxwc3pTdWJLZXksMCksbHBzekRhdGEsCgkJbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CgoJLyogb25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0CT0gUmVnT3BlbktleTMyVyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXkJPSBoa2V5OwoKCWxwZHdUeXBlCT0gUkVHX1NaOwoJcmV0CT0gUmVnUXVlcnlWYWx1ZUV4MzJXKAoJCXhoa2V5LAoJCU5VTEwsCQkvKiB2YXJuYW1lIE5VTEwgLT4gY29tcGF0ICovCgkJTlVMTCwJCS8qIGxwZHdSZXNlcnZlZCwgbXVzdCBiZSBOVUxMICovCgkJJmxwZHdUeXBlLAoJCShMUEJZVEUpbHBzekRhdGEsCgkJbHBjYkRhdGEKCSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnUXVlcnlWYWx1ZUV4QQkJW0FEVkFQSTMyLjE1N10gKi8KRFdPUkQgUmVnUXVlcnlWYWx1ZUV4MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCUxQQllURQlidWY7CglEV09SRAlyZXQsbXl4bGVuOwoJRFdPUkQJKm15bGVuOwoJRFdPUkQJdHlwZTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWVFeDMyQSgleCwlcywlcCwlcCwlcCwlbGQpXG4tPiIsCgkJaGtleSxscHN6VmFsdWVOYW1lLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoJaWYgKGxwYkRhdGEpIHsKCQkvKiBkb3VibGUgYnVmZmVyICovCgkJYnVmCT0gKExQQllURSl4bWFsbG9jKCgqbHBjYkRhdGEpKjIpOwoJCW15eGxlbgk9ICpscGNiRGF0YSoyOwoJCW15bGVuCT0gJm15eGxlbjsKCX0gZWxzZSB7CgkJYnVmPU5VTEw7CgkJaWYgKGxwY2JEYXRhKSB7CgkJCW15eGxlbgk9ICpscGNiRGF0YSoyOwoJCQlteWxlbgk9ICZteXhsZW47CgkJfSBlbHNlCgkJCW15bGVuCT0gTlVMTDsKCX0KCWlmIChscHN6VmFsdWVOYW1lKQoJCWxwc3pWYWx1ZU5hbWVXPXN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UgCgkJbHBzelZhbHVlTmFtZVc9TlVMTDsKCglpZiAobHBkd1R5cGUpCgkJdHlwZT0qbHBkd1R5cGU7CglyZXQ9UmVnUXVlcnlWYWx1ZUV4MzJXKAoJCWhrZXksCgkJbHBzelZhbHVlTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCSZ0eXBlLAoJCWJ1ZiwKCQlteWxlbgoJKTsKCWlmIChscGR3VHlwZSkgCgkJKmxwZHdUeXBlPXR5cGU7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJaWYgKGJ1ZikgewoJCQlpZiAoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgewoJCQkJLyogY29udmVydCBVTklDT0RFIHRvIEFTQ0lJICovCgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpYnVmKTsKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCQl9IGVsc2UgewoJCQkJaWYgKG15eGxlbj4qbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGJ1ZixteXhsZW4pOwoKCQkJCSpscGNiRGF0YQk9IG15eGxlbjsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCQl9Cgl9IGVsc2UgewoJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJfQoJaWYgKGJ1ZikKCQlmcmVlKGJ1Zik7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdRdWVyeVZhbHVlRXgJCVtLRVJORUwuMjI1XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlRXgxNigKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWVFeDE2KCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsCgkJaGtleSxscHN6VmFsdWVOYW1lLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoJcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQloa2V5LAoJCWxwc3pWYWx1ZU5hbWUsCgkJbHBkd1Jlc2VydmVkLAoJCWxwZHdUeXBlLAoJCWxwYkRhdGEsCgkJbHBjYkRhdGEKCSk7Cn0KCi8qIFJlZ1F1ZXJ5VmFsdWVBCQlbQURWQVBJMzIuMTU2XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelN1YktleSwKCUxQU1RSCWxwc3pEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlMzJBKCV4LCVzLCVwLCVsZClcbiIsCgkJaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoKCS8qIG9ubHkgb3BlbiBzdWJrZXksIGlmIHdlIHJlYWxseSBkbyBkZXNjZW5kICovCglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldAk9IFJlZ09wZW5LZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXkJPSBoa2V5OwoKCWxwZHdUeXBlCT0gUkVHX1NaOwoJcmV0CT0gUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCXhoa2V5LAoJCU5VTEwsCQkvKiBscHN6VmFsdWVOYW1lIE5VTEwgLT4gY29tcGF0ICovCgkJTlVMTCwJCS8qIGxwZHdSZXNlcnZlZCwgbXVzdCBiZSBOVUxMICovCgkJJmxwZHdUeXBlLAoJCShMUEJZVEUpbHBzekRhdGEsCgkJbHBjYkRhdGEKCSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnUXVlcnlWYWx1ZQkJW1NIRUxMLjZdIFtLRVJORUwuMjI0XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlMTYoCglIS0VZCWhrZXksCglMUFNUUglscHN6U3ViS2V5LAoJTFBTVFIJbHBzekRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlMTYoJXgsJXMsJXAsJWxkKVxuIiwKCQloa2V5LGxwc3pTdWJLZXksbHBzekRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CgkvKiBIQUNLOiB0aGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcwoJICogICAgICAgYW55d2F5LCBzbyB3ZSBqdXN0IG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4KCSAqICAgICAgICh0aGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5OykgaG9wZWZ1bGx5IGZpeGVzIEFsZHVzIEZINCkKCSAqLwoJaWYgKGxwY2JEYXRhKQoJCSpscGNiRGF0YSAmPSAweEZGRkY7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZTMyQShoa2V5LGxwc3pTdWJLZXksbHBzekRhdGEsbHBjYkRhdGEpOwp9CgovKgogKiBTZXR0aW5nIHZhbHVlcyBvZiBSZWdpc3RyeSBrZXlzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdTZXRWYWx1ZTE2IC0+IFJlZ1NldFZhbHVlMzJBIC0+IFJlZ1NldFZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlMzJXICAgLT4gUmVnU2V0VmFsdWVFeDMyVwogKi8KCi8qIFJlZ1NldFZhbHVlRXhXCQlbQURWQVBJMzIuMTcwXSAqLwpEV09SRCBSZWdTZXRWYWx1ZUV4MzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pWYWx1ZU5hbWUsCglEV09SRAlkd1Jlc2VydmVkLAoJRFdPUkQJZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglEV09SRAljYkRhdGEKKSB7CglMUEtFWVNUUlVDVAlscGtleTsKCWludAkJaTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlRXgzMlcoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLAoJCWhrZXksVzJDKGxwc3pWYWx1ZU5hbWUsMCksZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEKCSk7CgkvKiB3ZSBubyBsb25nZXIgY2FyZSBhYm91dCB0aGUgbHBiRGF0YSB0eXBlIGhlcmUuLi4gKi8KCWxwa2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgoJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXAzMlcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkJKGxwa2V5LT5ucm9mdmFsdWVzKzEpKnNpemVvZihLRVlWQUxVRSkKCQkJCSk7CgkJbHBrZXktPm5yb2Z2YWx1ZXMrKzsKCQltZW1zZXQobHBrZXktPnZhbHVlcytpLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7Cgl9CglpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCWlmIChscHN6VmFsdWVOYW1lKQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBzdHJkdXBXKGxwc3pWYWx1ZU5hbWUpOwoJCWVsc2UKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gTlVMTDsKCWxwa2V5LT52YWx1ZXNbaV0ubGVuCT0gY2JEYXRhOwoJbHBrZXktPnZhbHVlc1tpXS50eXBlCT0gZHdUeXBlOwoJaWYgKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSAhPU5VTEwpCgkJZnJlZShscGtleS0+dmFsdWVzW2ldLmRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5kYXRhCT0gKExQQllURSl4bWFsbG9jKGNiRGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmxhc3Rtb2RpZmllZCA9IHRpbWUoTlVMTCk7CgltZW1jcHkobHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwYkRhdGEsY2JEYXRhKTsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdTZXRWYWx1ZUV4QQkJW0FEVkFQSTMyLjE2OV0gKi8KRFdPUkQgUmVnU2V0VmFsdWVFeDMyQSgKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglEV09SRAlkd1Jlc2VydmVkLAoJRFdPUkQJZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglEV09SRAljYkRhdGEKKSB7CglMUEJZVEUJYnVmOwoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVFeDMyQSgleCwlcywlbGQsJWxkLCVwLCVsZClcbi0+IiwKCQloa2V5LGxwc3pWYWx1ZU5hbWUsZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEKCSk7CglpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCWJ1Zj0oTFBCWVRFKXN0cmR1cEEyVyhscGJEYXRhKTsKCQljYkRhdGE9MipzdHJsZW4obHBiRGF0YSkrMjsKCX0gZWxzZQoJCWJ1Zj1scGJEYXRhOwoJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJbHBzelZhbHVlTmFtZVcgPSBzdHJkdXBBMlcobHBzelZhbHVlTmFtZSk7CgllbHNlCgkJbHBzelZhbHVlTmFtZVcgPSBOVUxMOwoJcmV0PVJlZ1NldFZhbHVlRXgzMlcoaGtleSxscHN6VmFsdWVOYW1lVyxkd1Jlc2VydmVkLGR3VHlwZSxidWYsY2JEYXRhKTsKCWlmIChscHN6VmFsdWVOYW1lVykKCQlmcmVlKGxwc3pWYWx1ZU5hbWVXKTsKCWlmIChidWYhPWxwYkRhdGEpCgkJZnJlZShidWYpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnU2V0VmFsdWVFeAkJW0tFUk5FTC4yMjZdICovCkRXT1JEIFJlZ1NldFZhbHVlRXgxNigKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglEV09SRAlkd1Jlc2VydmVkLAoJRFdPUkQJZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglEV09SRAljYkRhdGEKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlRXgxNigleCwlcywlbGQsJWxkLCVwLCVsZClcbi0+IiwKCQloa2V5LGxwc3pWYWx1ZU5hbWUsZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEKCSk7CglyZXR1cm4gUmVnU2V0VmFsdWVFeDMyQShoa2V5LGxwc3pWYWx1ZU5hbWUsZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEpOwp9CgovKiBSZWdTZXRWYWx1ZVcJCQlbQURWQVBJMzIuMTcxXSAqLwpEV09SRCBSZWdTZXRWYWx1ZTMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCURXT1JECWR3VHlwZSwKCUxQQ1dTVFIJbHBzekRhdGEsCglEV09SRAljYkRhdGEKKSB7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWUzMlcoJXgsJXMsJWxkLCVzLCVsZClcbi0+IiwKCQloa2V5LFcyQyhscHN6U3ViS2V5LDApLGR3VHlwZSxXMkMobHBzekRhdGEsMCksY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MzJXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJZnByaW50ZihzdGRkZWIsIlJlZ1NldFZhbHVlWCBjYWxsZWQgd2l0aCBkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzIpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlWCBjYWxsZWQgd2l0aCBsZW49JWxkICE9IHN0cmxlbiglcykrMT0lZCFcbiIsCgkJCWNiRGF0YSxXMkMobHBzekRhdGEsMCksMipsc3RybGVuMzJXKGxwc3pEYXRhKSsyCgkJKTsKCQljYkRhdGE9Mipsc3RybGVuMzJXKGxwc3pEYXRhKSsyOwoJfQoJcmV0PVJlZ1NldFZhbHVlRXgzMlcoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoaGtleSE9eGhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKCn0KLyogUmVnU2V0VmFsdWVBCQkJW0FEVkFQSTMyLjE2OF0gKi8KRFdPUkQgUmVnU2V0VmFsdWUzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCURXT1JECWR3VHlwZSwKCUxQQ1NUUglscHN6RGF0YSwKCURXT1JECWNiRGF0YQopIHsKCURXT1JECXJldDsKCUhLRVkJeGhrZXk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZTMyQSgleCwlcywlbGQsJXMsJWxkKVxuLT4iLAoJCWhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MTYoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CgoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZUEgY2FsbGVkIHdpdGggZHdUeXBlPSVsZCFcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9c3RybGVuKGxwc3pEYXRhKSsxKQoJCWNiRGF0YT1zdHJsZW4obHBzekRhdGEpKzE7CglyZXQ9UmVnU2V0VmFsdWVFeDMyQSh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdTZXRWYWx1ZQkJCVtLRVJORUwuMjIxXSBbU0hFTEwuNV0gKi8KRFdPUkQgUmVnU2V0VmFsdWUxNigKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdUeXBlLAoJTFBDU1RSCWxwc3pEYXRhLAoJRFdPUkQJY2JEYXRhCikgewoJRFdPUkQJcmV0OwoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZTE2KCV4LCVzLCVsZCwlcywlbGQpXG4tPiIsCgkJaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEKCSk7CglyZXQ9UmVnU2V0VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwoJcmV0dXJuIHJldDsKfQoKLyogCiAqIEtleSBFbnVtZXJhdGlvbgogKgogKiBDYWxscGF0aDoKICogUmVnRW51bUtleTE2IC0+IFJlZ0VudW1LZXkzMkEgLT4gUmVnRW51bUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdFbnVtS2V5MzJXICAgLT4gUmVnRW51bUtleUV4MzJXCiAqLwoKLyogUmVnRW51bUtleUV4VwkJW0FEVkFQSTMyLjEzOV0gKi8KRFdPUkQgUmVnRW51bUtleUV4MzJXKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQV1NUUglscHN6TmFtZSwKCUxQRFdPUkQJbHBjY2hOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUFdTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJRklMRVRJTUUJKmZ0CikgewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bUtleUV4MzJXKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSwqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdAoJKTsKCWxwa2V5PWxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKCFscGtleS0+bmV4dHN1YikKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWxweGtleT1scGtleS0+bmV4dHN1YjsKCXdoaWxlIChpU3Via2V5ICYmIGxweGtleSkgewoJCWlTdWJrZXktLTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJaWYgKGlTdWJrZXkgfHwgIWxweGtleSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWlmICgyKmxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKSsyPipscGNjaE5hbWUpCgkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCW1lbWNweShscHN6TmFtZSxscHhrZXktPmtleW5hbWUsbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKjIrMik7CglpZiAobHBzekNsYXNzKSB7CgkJLyogd2hhdCBzaG91bGQgd2Ugd3JpdGUgaW50byBpdD8gKi8KCQkqbHBzekNsYXNzCQk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgp9CgovKiBSZWdFbnVtS2V5VwkJCVtBRFZBUEkzMi4xNDBdICovCkRXT1JEIFJlZ0VudW1LZXkzMlcoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBXU1RSCWxwc3pOYW1lLAoJRFdPUkQJbHBjY2hOYW1lCikgewoJRklMRVRJTUUJZnQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5MzJXKCV4LCVsZCwlcCwlbGQpXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZQoJKTsKCXJldHVybiBSZWdFbnVtS2V5RXgzMlcoaGtleSxpU3Via2V5LGxwc3pOYW1lLCZscGNjaE5hbWUsTlVMTCxOVUxMLE5VTEwsJmZ0KTsKfQovKiBSZWdFbnVtS2V5RXhBCQlbQURWQVBJMzIuMTM4XSAqLwpEV09SRCBSZWdFbnVtS2V5RXgzMkEoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBTVFIJbHBzek5hbWUsCglMUERXT1JECWxwY2NoTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJRklMRVRJTUUJKmZ0CikgewoJRFdPUkQJcmV0LGxwY2NoTmFtZVcsbHBjY2hDbGFzc1c7CglMUFdTVFIJbHBzek5hbWVXLGxwc3pDbGFzc1c7CgoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bUtleUV4MzJBKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLCpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0CgkpOwoJaWYgKGxwc3pOYW1lKSB7CgkJbHBzek5hbWVXCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaE5hbWUqMik7CgkJbHBjY2hOYW1lVwk9ICpscGNjaE5hbWUqMjsKCX0gZWxzZSB7CgkJbHBzek5hbWVXCT0gTlVMTDsKCQlscGNjaE5hbWVXIAk9IDA7Cgl9CglpZiAobHBzekNsYXNzKSB7CgkJbHBzekNsYXNzVwkJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MqMik7CgkJbHBjY2hDbGFzc1cJPSAqbHBjY2hDbGFzcyoyOwoJfSBlbHNlIHsKCQlscHN6Q2xhc3NXCT0wOwoJCWxwY2NoQ2xhc3NXPTA7Cgl9CglyZXQ9UmVnRW51bUtleUV4MzJXKAoJCWhrZXksCgkJaVN1YmtleSwKCQlscHN6TmFtZVcsCgkJJmxwY2NoTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJJmxwY2NoQ2xhc3NXLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pOYW1lLGxwc3pOYW1lVyk7CgkJKmxwY2NoTmFtZT1zdHJsZW4obHBzek5hbWUpOwoJCWlmIChscHN6Q2xhc3NXKSB7CgkJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCQkJKmxwY2NoQ2xhc3M9c3RybGVuKGxwc3pDbGFzcyk7CgkJfQoJfQoJaWYgKGxwc3pOYW1lVykKCQlmcmVlKGxwc3pOYW1lVyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnRW51bUtleUEJCQlbQURWQVBJMzIuMTM3XSAqLwpEV09SRCBSZWdFbnVtS2V5MzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQU1RSCWxwc3pOYW1lLAoJRFdPUkQJbHBjY2hOYW1lCikgewoJRklMRVRJTUUJZnQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5MzJBKCV4LCVsZCwlcCwlbGQpXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZQoJKTsKCXJldHVybglSZWdFbnVtS2V5RXgzMkEoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lLAoJCSZscGNjaE5hbWUsCgkJTlVMTCwKCQlOVUxMLAoJCU5VTEwsCgkJJmZ0CgkpOwp9CgovKiBSZWdFbnVtS2V5CQkJW1NIRUxMLjddIFtLRVJORUwuMjE2XSAqLwpEV09SRCBSZWdFbnVtS2V5MTYoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBTVFIJbHBzek5hbWUsCglEV09SRAlscGNjaE5hbWUKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0VudW1LZXkxNigleCwlbGQsJXAsJWxkKVxuLT4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUKCSk7CglyZXR1cm4gUmVnRW51bUtleTMyQShoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKfQoKLyogCiAqIEVudW1lcmF0ZSBSZWdpc3RyeSBWYWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1WYWx1ZTE2IC0+IFJlZ0VudW1WYWx1ZTMyQSAtPiBSZWdFbnVtVmFsdWUzMlcKICovCgovKiBSZWdFbnVtVmFsdWVXCQlbQURWQVBJMzIuMTQyXSAqLwpEV09SRCBSZWdFbnVtVmFsdWUzMlcoCglIS0VZCWhrZXksCglEV09SRAlpVmFsdWUsCglMUFdTVFIJbHBzelZhbHVlLAoJTFBEV09SRAlscGNjaFZhbHVlLAoJTFBEV09SRAlscGRSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bVZhbHVlMzJXKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YQoJKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBrZXktPm5yb2Z2YWx1ZXM8PWlWYWx1ZSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCXZhbAk9IGxwa2V5LT52YWx1ZXMraVZhbHVlOwoKCWlmICh2YWwtPm5hbWUpIHsKCQlpZiAobHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMj4qbHBjY2hWYWx1ZSkgewoJCQkqbHBjY2hWYWx1ZSA9IGxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscHN6VmFsdWUsdmFsLT5uYW1lLDIqbHN0cmxlbjMyVyh2YWwtPm5hbWUpKzIpOwoJCSpscGNjaFZhbHVlPWxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7Cgl9IGVsc2UgewoJCS8qIGhvdyB0byBoYW5kbGUgTlVMTCB2YWx1ZT8gKi8KCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDI7Cgl9CgkqbHBkd1R5cGU9dmFsLT50eXBlOwoJaWYgKGxwYkRhdGEpIHsKCQlpZiAodmFsLT5sZW4+KmxwY2JEYXRhKQoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCW1lbWNweShscGJEYXRhLHZhbC0+ZGF0YSx2YWwtPmxlbik7CgkJKmxwY2JEYXRhID0gdmFsLT5sZW47Cgl9CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnRW51bVZhbHVlQQkJW0FEVkFQSTMyLjE0MV0gKi8KRFdPUkQgUmVnRW51bVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVZhbHVlLAoJTFBTVFIJbHBzelZhbHVlLAoJTFBEV09SRAlscGNjaFZhbHVlLAoJTFBEV09SRAlscGRSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUFdTVFIJbHBzelZhbHVlVzsKCUxQQllURQlscGJEYXRhVzsKCURXT1JECXJldCxscGNiRGF0YVc7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtVmFsdWUzMkEoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhCgkpOwoKCWxwc3pWYWx1ZVcgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoVmFsdWUqMik7CglpZiAobHBiRGF0YSkgewoJCWxwYkRhdGFXID0gKExQQllURSl4bWFsbG9jKCpscGNiRGF0YSoyKTsKCQlscGNiRGF0YVcgPSAqbHBjYkRhdGEqMjsKCX0gZWxzZQoJCWxwYkRhdGFXID0gTlVMTDsKCXJldD1SZWdFbnVtVmFsdWUzMlcoCgkJaGtleSwKCQlpVmFsdWUsCgkJbHBzelZhbHVlVywKCQlscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLAoJCWxwZHdUeXBlLAoJCWxwYkRhdGFXLAoJCSZscGNiRGF0YVcKCSk7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pWYWx1ZSxscHN6VmFsdWVXKTsKCQlpZiAobHBiRGF0YSkgewoJCQlpZiAoKDE8PCpscGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWxwYkRhdGFXKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChscGNiRGF0YVcgPiAqbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGxwYkRhdGFXLGxwY2JEYXRhVyk7CgkJCX0KCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCX0KCX0KCWlmIChscGJEYXRhVykKCQlmcmVlKGxwYkRhdGFXKTsKCWlmIChscHN6VmFsdWVXKQoJCWZyZWUobHBzelZhbHVlVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdFbnVtVmFsdWUJCQlbS0VSTkVMLjIyM10gKi8KRFdPUkQgUmVnRW51bVZhbHVlMTYoCglIS0VZCWhrZXksCglEV09SRAlpVmFsdWUsCglMUFNUUglscHN6VmFsdWUsCglMUERXT1JECWxwY2NoVmFsdWUsCglMUERXT1JECWxwZFJlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bVZhbHVlKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YQoJKTsKCXJldHVybiBSZWdFbnVtVmFsdWUzMkEoCgkJaGtleSwKCQlpVmFsdWUsCgkJbHBzelZhbHVlLAoJCWxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YSwKCQlscGNiRGF0YQoJKTsKfQoKLyogCiAqICBDbG9zZSByZWdpc3RyeSBrZXkKICovCi8qIFJlZ0Nsb3NlS2V5CQkJW1NIRUxMLjNdIFtLRVJORUwuMjIwXSBbQURWQVBJMzIuMTI2XSAqLwpEV09SRCBSZWdDbG9zZUtleShIS0VZIGhrZXkpIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ2xvc2VLZXkoJXgpXG4iLGhrZXkpOwoJcmVtb3ZlX2hhbmRsZShoa2V5KTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9Ci8qIAogKiBEZWxldGUgcmVnaXN0cnkga2V5CiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVLZXkxNiAtPiBSZWdEZWxldGVLZXkzMkEgLT4gUmVnRGVsZXRlS2V5MzJXCiAqLwovKiBSZWdEZWxldGVLZXlXCQlbQURWQVBJMzIuMTM0XSAqLwpEV09SRCBSZWdEZWxldGVLZXkzMlcoSEtFWSBoa2V5LExQV1NUUiBscHN6U3ViS2V5KSB7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdEZWxldGVLZXkzMlcoJXgsJXMpXG4iLAoJCWhrZXksVzJDKGxwc3pTdWJLZXksMCkKCSk7CglscE5leHRLZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBOZXh0S2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgkvKiB3ZSBuZWVkIHRvIGtub3cgdGhlIHByZXZpb3VzIGtleSBpbiB0aGUgaGllci4gKi8KCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKGk8d3BjLTEpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCS8qIG5vdCBmb3VuZCBpcyBzdWNjZXNzICovCgkJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJbHB4a2V5CT0gbHBOZXh0S2V5LT5uZXh0c3ViOwoJbHBscFByZXZLZXkgPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJCT0gbHB4a2V5LT5uZXh0OwoJfQoJaWYgKCFscHhrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7CglpZiAobHB4a2V5LT5uZXh0c3ViKQoJCXJldHVybiBTSEVMTF9FUlJPUl9DQU5UV1JJVEU7CgkqbHBscFByZXZLZXkJPSBscHhrZXktPm5leHQ7CglmcmVlKGxweGtleS0+a2V5bmFtZSk7CglpZiAobHB4a2V5LT5jbGFzcykKCQlmcmVlKGxweGtleS0+Y2xhc3MpOwoJaWYgKGxweGtleS0+dmFsdWVzKQoJCWZyZWUobHB4a2V5LT52YWx1ZXMpOwoJZnJlZShscHhrZXkpOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybglTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdEZWxldGVLZXlBCQlbQURWQVBJMzIuMTMzXSAqLwpEV09SRCBSZWdEZWxldGVLZXkzMkEoSEtFWSBoa2V5LExQQ1NUUiBscHN6U3ViS2V5KSB7CglMUFdTVFIJbHBzelN1YktleVc7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdEZWxldGVLZXkzMkEoJXgsJXMpXG4iLAoJCWhrZXksbHBzelN1YktleQoJKTsKCWxwc3pTdWJLZXlXPUhFQVBfc3RyZHVwQXRvVyhHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelN1YktleSk7CglyZXQ9UmVnRGVsZXRlS2V5MzJXKGhrZXksbHBzelN1YktleVcpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pTdWJLZXlXKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ0RlbGV0ZUtleQkJCVtTSEVMTC40XSBbS0VSTkVMLjIxOV0gKi8KRFdPUkQgUmVnRGVsZXRlS2V5MTYoSEtFWSBoa2V5LExQQ1NUUiBscHN6U3ViS2V5KSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0RlbGV0ZUtleTE2KCV4LCVzKVxuIiwKCQloa2V5LGxwc3pTdWJLZXkKCSk7CglyZXR1cm4gUmVnRGVsZXRlS2V5MzJBKGhrZXksbHBzelN1YktleSk7Cn0KCi8qIAogKiBEZWxldGUgcmVnaXN0cnkgdmFsdWUKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZVZhbHVlMTYgLT4gUmVnRGVsZXRlVmFsdWUzMkEgLT4gUmVnRGVsZXRlVmFsdWUzMlcKICovCi8qIFJlZ0RlbGV0ZVZhbHVlVwkJW0FEVkFQSTMyLjEzNl0gKi8KRFdPUkQgUmVnRGVsZXRlVmFsdWUzMlcoSEtFWSBoa2V5LExQV1NUUiBscHN6VmFsdWUpIHsKCURXT1JECQlpOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0RlbGV0ZVZhbHVlMzJXKCV4LCVzKVxuIiwKCQloa2V5LFcyQyhscHN6VmFsdWUsMCkKCSk7CglscGtleT1sb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmIChscHN6VmFsdWUpIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21wMzJXKGxwa2V5LT52YWx1ZXNbaV0ubmFtZSxscHN6VmFsdWUpCgkJCSkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7LypGSVhNRTogY29ycmVjdCBlcnJvcmNvZGU/ICovCgl2YWwJPSBscGtleS0+dmFsdWVzK2k7CglpZiAodmFsLT5uYW1lKSBmcmVlKHZhbC0+bmFtZSk7CglpZiAodmFsLT5kYXRhKSBmcmVlKHZhbC0+ZGF0YSk7CgltZW1jcHkoCQoJCWxwa2V5LT52YWx1ZXMraSwKCQlscGtleS0+dmFsdWVzK2krMSwKCQlzaXplb2YoS0VZVkFMVUUpKihscGtleS0+bnJvZnZhbHVlcy1pLTEpCgkpOwoJbHBrZXktPnZhbHVlcwk9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJbHBrZXktPnZhbHVlcywKCQkJCShscGtleS0+bnJvZnZhbHVlcy0xKSpzaXplb2YoS0VZVkFMVUUpCgkJCSk7CglscGtleS0+bnJvZnZhbHVlcy0tOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0RlbGV0ZVZhbHVlQQkJW0FEVkFQSTMyLjEzNV0gKi8KRFdPUkQgUmVnRGVsZXRlVmFsdWUzMkEoSEtFWSBoa2V5LExQU1RSIGxwc3pWYWx1ZSkgewoJTFBXU1RSCWxwc3pWYWx1ZVc7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoIHN0ZGRlYiwgIlJlZ0RlbGV0ZVZhbHVlMzJBKCV4LCVzKVxuIiwgaGtleSxscHN6VmFsdWUgKTsKICAgICAgICBscHN6VmFsdWVXPUhFQVBfc3RyZHVwQXRvVyhHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelZhbHVlKTsKCXJldD1SZWdEZWxldGVWYWx1ZTMyVyhoa2V5LGxwc3pWYWx1ZVcpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxscHN6VmFsdWVXKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ0RlbGV0ZVZhbHVlCQlbS0VSTkVMLjIyMl0gKi8KRFdPUkQgUmVnRGVsZXRlVmFsdWUxNihIS0VZIGhrZXksTFBTVFIgbHBzelZhbHVlKSB7CglkcHJpbnRmX3JlZyggc3RkZGViLCJSZWdEZWxldGVWYWx1ZTE2KCV4LCVzKVxuIiwgaGtleSxscHN6VmFsdWUgKTsKCXJldHVybiBSZWdEZWxldGVWYWx1ZTMyQShoa2V5LGxwc3pWYWx1ZSk7Cn0KCi8qIFJlZ0ZsdXNoS2V5CQkJW0FEVkFQSTMyLjE0M10gW0tFUk5FTC4yMjddICovCkRXT1JEIFJlZ0ZsdXNoS2V5KEhLRVkgaGtleSkgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdGbHVzaEtleSgleCksIFNUVUIuXG4iLGhrZXkpOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIEZJWE1FOiBscGNjaFhYWFggLi4uIGlzIHRoaXMgY291bnRpbmcgaW4gV0NIQVJTIG9yIGluIEJZVEVzID8/ICovCgovKiBSZWdRdWVyeUluZm9LZXlXCQlbQURWQVBJMzIuMTUzXSAqLwpEV09SRCBSZWdRdWVyeUluZm9LZXkzMlcoCglIS0VZCWhrZXksCglMUFdTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwY1N1YktleXMsCglMUERXT1JECWxwY2NoTWF4U3Via2V5LAoJTFBEV09SRAlscGNjaE1heENsYXNzLAoJTFBEV09SRAlscGNWYWx1ZXMsCglMUERXT1JECWxwY2NoTWF4VmFsdWVOYW1lLAoJTFBEV09SRAlscGNjYk1heFZhbHVlRGF0YSwKCUxQRFdPUkQJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCUZJTEVUSU1FCSpmdAopIHsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCWludAkJbnJvZmtleXMsbWF4c3Via2V5LG1heGNsYXNzLG1heHZhbHVlcyxtYXh2bmFtZSxtYXh2ZGF0YTsKCWludAkJaTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5SW5mb0tleTMyVygleCwuLi4uLi4pXG4iLGhrZXkpOwoJbHBrZXk9bG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBzekNsYXNzKSB7CgkJaWYgKGxwa2V5LT5jbGFzcykgewoJCQlpZiAobHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjIrMj4qbHBjY2hDbGFzcykgewoJCQkJKmxwY2NoQ2xhc3M9bHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQltZW1jcHkobHBzekNsYXNzLGxwa2V5LT5jbGFzcyxsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykpOwoJCX0gZWxzZSB7CgkJCSpscHN6Q2xhc3MJPSAwOwoJCQkqbHBjY2hDbGFzcwk9IDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAobHBjY2hDbGFzcykKCQkJKmxwY2NoQ2xhc3MJPSBsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCX0KCWxweGtleT1scGtleS0+bmV4dHN1YjsKCW5yb2ZrZXlzPW1heHN1YmtleT1tYXhjbGFzcz1tYXh2YWx1ZXM9bWF4dm5hbWU9bWF4dmRhdGE9MDsKCXdoaWxlIChscHhrZXkpIHsKCQlucm9ma2V5cysrOwoJCWlmIChsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSk+bWF4c3Via2V5KQoJCQltYXhzdWJrZXk9bHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpOwoJCWlmIChscHhrZXktPmNsYXNzICYmIGxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk+bWF4Y2xhc3MpCgkJCW1heGNsYXNzPWxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk7CgkJaWYgKGxweGtleS0+bnJvZnZhbHVlcz5tYXh2YWx1ZXMpCgkJCW1heHZhbHVlcz1scHhrZXktPm5yb2Z2YWx1ZXM7CgkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCUxQS0VZVkFMVUUJdmFsPWxweGtleS0+dmFsdWVzK2k7CgoJCQlpZiAodmFsLT5uYW1lICYmIGxzdHJsZW4zMlcodmFsLT5uYW1lKT5tYXh2bmFtZSkKCQkJCW1heHZuYW1lPWxzdHJsZW4zMlcodmFsLT5uYW1lKTsKCQkJaWYgKHZhbC0+bGVuPm1heHZkYXRhKQoJCQkJbWF4dmRhdGE9dmFsLT5sZW47CgkJfQoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglpZiAoIW1heGNsYXNzKSBtYXhjbGFzcwk9IDE7CglpZiAoIW1heHZuYW1lKSBtYXh2bmFtZQk9IDE7CglpZiAobHBjU3ViS2V5cykKCQkqbHBjU3ViS2V5cwk9IG5yb2ZrZXlzOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleQk9IG1heHN1YmtleSoyOwoJaWYgKGxwY2NoTWF4Q2xhc3MpCgkJKmxwY2NoTWF4Q2xhc3MJPSBtYXhjbGFzcyoyOwoJaWYgKGxwY1ZhbHVlcykKCQkqbHBjVmFsdWVzCT0gbWF4dmFsdWVzOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZT0gbWF4dm5hbWU7CglpZiAobHBjY2JNYXhWYWx1ZURhdGEpCgkJKmxwY2NiTWF4VmFsdWVEYXRhPSBtYXh2ZGF0YTsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdRdWVyeUluZm9LZXlBCQlbQURWQVBJMzIuMTUyXSAqLwpEV09SRCBSZWdRdWVyeUluZm9LZXkzMkEoCglIS0VZCWhrZXksCglMUFNUUglscHN6Q2xhc3MsCglMUERXT1JECWxwY2NoQ2xhc3MsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQRFdPUkQJbHBjU3ViS2V5cywKCUxQRFdPUkQJbHBjY2hNYXhTdWJrZXksCglMUERXT1JECWxwY2NoTWF4Q2xhc3MsCglMUERXT1JECWxwY1ZhbHVlcywKCUxQRFdPUkQJbHBjY2hNYXhWYWx1ZU5hbWUsCglMUERXT1JECWxwY2NiTWF4VmFsdWVEYXRhLAoJTFBEV09SRAlscGNiU2VjdXJpdHlEZXNjcmlwdG9yLAoJRklMRVRJTUUJKmZ0CikgewoJTFBXU1RSCQlscHN6Q2xhc3NXOwoJRFdPUkQJCXJldDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5SW5mb0tleTMyQSgleCwuLi4uLi4pXG4iLGhrZXkpOwoJaWYgKGxwc3pDbGFzcykgewoJCSpscGNjaENsYXNzKj0gMjsKCQlscHN6Q2xhc3NXICA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyk7CgoJfSBlbHNlCgkJbHBzekNsYXNzVyAgPSBOVUxMOwoJcmV0PVJlZ1F1ZXJ5SW5mb0tleTMyVygKCQloa2V5LAoJCWxwc3pDbGFzc1csCgkJbHBjY2hDbGFzcywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBjU3ViS2V5cywKCQlscGNjaE1heFN1YmtleSwKCQlscGNjaE1heENsYXNzLAoJCWxwY1ZhbHVlcywKCQlscGNjaE1heFZhbHVlTmFtZSwKCQlscGNjYk1heFZhbHVlRGF0YSwKCQlscGNiU2VjdXJpdHlEZXNjcmlwdG9yLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykKCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CglpZiAobHBjY2hDbGFzcykKCQkqbHBjY2hDbGFzcy89MjsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkvPTI7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcy89MjsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWUvPTI7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQovKiBSZWdDb25uZWN0UmVnaXN0cnlBCQlbQURWQVBJMzIuMTI3XSAqLwpEV09SRCBSZWdDb25uZWN0UmVnaXN0cnkzMkEoTFBDU1RSIG1hY2hpbmUsSEtFWSBoa2V5LExQSEtFWSByZXNrZXkpIHsKCWZwcmludGYoc3RkZXJyLCJSZWdDb25uZWN0UmVnaXN0cnkzMkEoJXMsJTA4eCwlcCksIFNUVUIuXG4iLAoJCW1hY2hpbmUsaGtleSxyZXNrZXkKCSk7CglyZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7IC8qIEZJWE1FICovCn0K