LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtYWxsb2MuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9mY250bC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPHB3ZC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiZG9zX2ZzLmgiCiNpbmNsdWRlICJzdHJpbmczMi5oIgkKI2luY2x1ZGUgInN0ZGRlYnVnLmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojZGVmaW5lIE1BS0VfRFdPUkQoeCx5KSAoKERXT1JEKU1BS0VMT05HKHgseSkpCgovKiBGSVhNRTogZm9sbG93aW5nIGRlZmluZXMgc2hvdWxkIGJlIGNvbmZpZ3VyZWQgZ2xvYmFsIC4uLiAqLwoKLyogTk9URTogZG8gbm90IGFwcGVuZCBhIC8uIGxpbnV4JyBta2RpcigpIFdJTEwgRkFJTCBpZiB5b3UgZG8gdGhhdCAqLwojZGVmaW5lIFdJTkVfUFJFRklYCQkJIi8ud2luZSIKI2RlZmluZSBTQVZFX1VTRVJTX0RFRkFVTFQJCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQJIi91c3IvbG9jYWwvZXRjL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUgkJInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORQkJInN5c3RlbS5yZWciCgojZGVmaW5lIEtFWV9SRUdJU1RSWQkiU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5IgojZGVmaW5lIFZBTF9TQVZFVVBEQVRFRAkiU2F2ZU9ubHlVcGRhdGVkS2V5cyIKCi8qIG9uZSB2YWx1ZSBvZiBhIGtleSAqLwp0eXBlZGVmIHN0cnVjdCB0YWdLRVlWQUxVRQp7CiAgICBMUFdTVFIgICBuYW1lOyAgICAgICAgICAvKiBuYW1lIG9mIHZhbHVlIChVTklDT0RFKSBvciBOVUxMIGZvciB3aW4zMSAqLwogICAgRFdPUkQgICAgdHlwZTsgICAgICAgICAgLyogdHlwZSBvZiB2YWx1ZSAqLwogICAgRFdPUkQgICAgbGVuOyAgICAgICAgICAgLyogbGVuZ3RoIG9mIGRhdGEgKi8KICAgIERXT1JEICAgIGxhc3Rtb2RpZmllZDsgIC8qIHRpbWUgb2Ygc2Vjb25kcyBzaW5jZSAxLjEuMTk3MCAqLwogICAgTFBCWVRFICAgZGF0YTsgICAgICAgICAgLyogY29udGVudCwgbWF5IGJlIHN0cmluZ3MsIGJpbmFyaWVzLCBldGMuICovCn0gS0VZVkFMVUUsKkxQS0VZVkFMVUU7CgovKiBhIHJlZ2lzdHJ5IGtleSAqLwp0eXBlZGVmIHN0cnVjdCB0YWdLRVlTVFJVQ1QKewogICAgTFBXU1RSICAgICAgICAgICAgICAga2V5bmFtZTsgICAgICAgLyogbmFtZSBvZiBUSElTIGtleSAoVU5JQ09ERSkgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgIGZsYWdzOyAgICAgICAgIC8qIGZsYWdzLiAqLwogICAgTFBXU1RSICAgICAgICAgICAgICAgY2xhc3M7CiAgICAvKiB2YWx1ZXMgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgIG5yb2Z2YWx1ZXM7ICAgIC8qIG5yIG9mIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgTFBLRVlWQUxVRSAgICAgICAgICAgdmFsdWVzOyAgICAgICAgLyogdmFsdWVzIGluIFRISVMga2V5ICovCiAgICAvKiBrZXkgbWFuYWdlbWVudCBwb2ludGVycyAqLwogICAgc3RydWN0IHRhZ0tFWVNUUlVDVAkqbmV4dDsgICAgICAgICAgLyogbmV4dCBrZXkgb24gc2FtZSBoaWVyYXJjaHkgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHRzdWI7ICAgICAgIC8qIGtleXMgdGhhdCBoYW5nIGJlbG93IFRISVMga2V5ICovCn0gS0VZU1RSVUNULCAqTFBLRVlTVFJVQ1Q7CgoKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2NsYXNzZXNfcm9vdD1OVUxMOwkvKiB3aW5kb3dzIDMuMSBnbG9iYWwgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jdXJyZW50X3VzZXI9TlVMTDsJLyogdXNlciBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X2xvY2FsX21hY2hpbmU9TlVMTDsvKiBtYWNoaW5lIHNwZWNpZmljIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfdXNlcnM9TlVMTDsJLyogYWxsIHVzZXJzPyAqLwoKLyogZHluYW1pYywgbm90IHNhdmVkICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9wZXJmb3JtYW5jZV9kYXRhPU5VTEw7CnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jdXJyZW50X2NvbmZpZz1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfZHluX2RhdGE9TlVMTDsKCi8qIHdoYXQgdmFsdWV0eXBlcyBkbyB3ZSBuZWVkIHRvIGNvbnZlcnQ/ICovCiNkZWZpbmUgVU5JQ09OVk1BU0sJKCgxPDxSRUdfU1opfCgxPDxSRUdfTVVMVElfU1opfCgxPDxSRUdfRVhQQU5EX1NaKSkKCiNkZWZpbmUgc3RyZHVwQTJXKHgpCVNUUklORzMyX0R1cEFuc2lUb1VuaSh4KQojZGVmaW5lIHN0cmR1cFcyQSh4KQlTVFJJTkczMl9EdXBVbmlUb0Fuc2koeCkKI2RlZmluZSBzdHJkdXBXKHgpCVNUUklORzMyX3N0cmR1cFcoeCkKI2RlZmluZSBzdHJjbXBuaVcoYSxiKQlTVFJJTkczMl9sc3RyY21wbmlXKGEsYikKI2RlZmluZSBzdHJjaHJXKGEsYykJU1RSSU5HMzJfbHN0cmNoclcoYSxjKQojZGVmaW5lIHN0cmNweVdBKGEsYikJU1RSSU5HMzJfVW5pVG9BbnNpKGEsYikKCnN0YXRpYyBzdHJ1Y3Qgb3BlbmhhbmRsZSB7CglMUEtFWVNUUlVDVAlscGtleTsKCUhLRVkJCWhrZXk7CglSRUdTQU0JCWFjY2Vzc21hc2s7Cn0gICpvcGVuaGFuZGxlcz1OVUxMOwpzdGF0aWMgaW50CW5yb2ZvcGVuaGFuZGxlcz0wOwpzdGF0aWMgaW50CWN1cnJlbnRoYW5kbGU9MTsKCnN0YXRpYyB2b2lkCmFkZF9oYW5kbGUoSEtFWSBoa2V5LExQS0VZU1RSVUNUIGxwa2V5LFJFR1NBTSBhY2Nlc3NtYXNrKSB7CglpbnQJaTsKCglmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspIHsKCQlpZiAob3BlbmhhbmRsZXNbaV0ubHBrZXk9PWxwa2V5KSB7CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiYWRkX2hhbmRsZTpUcmllZCB0byBhZGQgJXAgdHdpY2UhXG4iLGxwa2V5KTsKCQl9CgkJaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKCQkJZHByaW50Zl9yZWcoc3RkZGViLCJhZGRfaGFuZGxlOlRyaWVkIHRvIGFkZCAlbHggdHdpY2UhXG4iLChMT05HKWhrZXkpOwoJCX0KCX0KCW9wZW5oYW5kbGVzPXhyZWFsbG9jKAlvcGVuaGFuZGxlcywKCQkJCXNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKQoJCSk7CglvcGVuaGFuZGxlc1tpXS5scGtleQk9IGxwa2V5OwoJb3BlbmhhbmRsZXNbaV0uaGtleQk9IGhrZXk7CglvcGVuaGFuZGxlc1tpXS5hY2Nlc3NtYXNrPSBhY2Nlc3NtYXNrOwoJbnJvZm9wZW5oYW5kbGVzKys7Cn0KCnN0YXRpYyBMUEtFWVNUUlVDVApnZXRfaGFuZGxlKEhLRVkgaGtleSkgewoJaW50CWk7CgoJZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQoJCWlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQoJCQlyZXR1cm4gb3BlbmhhbmRsZXNbaV0ubHBrZXk7CglkcHJpbnRmX3JlZyhzdGRkZWIsImdldF9oYW5kbGU6RGlkbid0IGZpbmQgaGFuZGxlICVseD9cbiIsKExPTkcpaGtleSk7CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQKcmVtb3ZlX2hhbmRsZShIS0VZIGhrZXkpIHsKCWludAlpOwoKCWZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykKCQlpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkKCQkJYnJlYWs7CglpZiAoaT09bnJvZm9wZW5oYW5kbGVzKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJyZW1vdmVfaGFuZGxlOkRpZG4ndCBmaW5kIGhhbmRsZSAlMDh4P1xuIixoa2V5KTsKCQlyZXR1cm47Cgl9CgltZW1jcHkoCW9wZW5oYW5kbGVzK2ksCgkJb3BlbmhhbmRsZXMraSsxLAoJCXNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCgkpOwoJb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKCW5yb2ZvcGVuaGFuZGxlcy0tOwoJcmV0dXJuOwp9CgoKLyogZGVidWcgZnVuY3Rpb24sIGNvbnZlcnRzIGEgdW5pY29kZSBpbnRvIGEgc3RhdGljIG1lbW9yeSBhcmVhIAogKiAoc3ViIGZvciB1c2luZyB0d28gc3RhdGljIHN0cmluZ3MsIGluIGNhc2Ugd2UgbmVlZCB0aGVtIGluIGEgc2luZ2xlIGNhbGwpCiAqLwpMUFNUUgpXMkMoTFBDV1NUUiB4LGludCBzdWIpIHsKCXN0YXRpYwlMUFNUUgl1bmljb2RlZGVidWdbMl09e05VTEwsTlVMTH07CglpZiAoeD09TlVMTCkKCQlyZXR1cm4gIjxOVUxMPiI7CglpZiAoc3ViIT0wICYmIHN1YiE9MSkKCQlyZXR1cm4gIjxXMkM6YmFkIHN1Yj4iOwoJaWYgKHVuaWNvZGVkZWJ1Z1tzdWJdKSBmcmVlKHVuaWNvZGVkZWJ1Z1tzdWJdKTsKCXVuaWNvZGVkZWJ1Z1tzdWJdCT0gc3RyZHVwVzJBKHgpOwoJcmV0dXJuIHVuaWNvZGVkZWJ1Z1tzdWJdOwp9CgpzdGF0aWMgTFBLRVlTVFJVQ1QKbG9va3VwX2hrZXkoSEtFWSBoa2V5KSB7Cglzd2l0Y2ggKGhrZXkpIHsKCWNhc2UgMHgwMDAwMDAwMDoKCWNhc2UgMHgwMDAwMDAwMToKCWNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6CgkJcmV0dXJuIGtleV9jbGFzc2VzX3Jvb3Q7CgljYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgoJCXJldHVybiBrZXlfY3VycmVudF91c2VyOwoJY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CgkJcmV0dXJuIGtleV9sb2NhbF9tYWNoaW5lOwoJY2FzZSBIS0VZX1VTRVJTOgoJCXJldHVybiBrZXlfdXNlcnM7CgljYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKCQlyZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgljYXNlIEhLRVlfRFlOX0RBVEE6CgkJcmV0dXJuIGtleV9keW5fZGF0YTsKCWNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKCQlyZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoJZGVmYXVsdDoKCQlkcHJpbnRmX3JlZyhzdGRkZWIsImxvb2t1cF9oa2V5KCVseCksIHNwZWNpYWwga2V5IVxuIiwKCQkJKExPTkcpaGtleQoJCSk7CgkJcmV0dXJuIGdldF9oYW5kbGUoaGtleSk7Cgl9CgkvKk5PVFJFQUNIRUQqLwp9CgovKiAKICogc3BsaXRzIHRoZSB1bmljb2RlIHN0cmluZyAnd3AnIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KICogdGhlIGFycmF5IGlzIGFsbG9jYXRlZCBieSB0aGlzIGZ1bmN0aW9uLiAKICogdGhlIG51bWJlciBvZiBjb21wb25lbnRzIHdpbGwgYmUgc3RvcmVkIGluICd3cGMnCiAqIEZyZWUgdGhlIGFycmF5IHVzaW5nIEZSRUVfS0VZX1BBVEgKICovCnN0YXRpYyB2b2lkCnNwbGl0X2tleXBhdGgoTFBDV1NUUiB3cCxMUFdTVFIgKip3cHYsaW50ICp3cGMpIHsKCWludAlpLGosbGVuOwoJTFBXU1RSCXdzOwoKCXdzCT0gc3RyZHVwVyh3cCk7Cgkqd3BjCT0gMTsKCWZvciAoaT0wO3dzW2ldO2krKykgewoJCWlmICh3c1tpXT09J1xcJykgewoJCQl3c1tpXT0wOwoJCQkoKndwYykrKzsKCQl9Cgl9CglsZW4JPSBpOwoJKndwdgk9IChMUFdTVFIqKXhtYWxsb2Moc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwoJKCp3cHYpWzBdPSB3czsKCWoJPSAxOwoJZm9yIChpPTE7aTxsZW47aSsrKQoJCWlmICh3c1tpLTFdPT0wKQoJCQkoKndwdilbaisrXT13cytpOwoJKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRICWZyZWUod3BzWzBdKTtmcmVlKHdwcyk7CgovKgogKiBTaGVsbCBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIGtleXMuIAogKi8Kdm9pZCBTSEVMTF9TdGFydHVwUmVnaXN0cnkoKTsKdm9pZApTSEVMTF9Jbml0KCkgewoJc3RydWN0CXBhc3N3ZAkqcHdkOwoKCUhLRVkJY2xfcl9oa2V5LGNfdV9oa2V5OwojZGVmaW5lIEFERF9ST09UX0tFWSh4eCkgXAoJeHggPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7XAoJbWVtc2V0KHh4LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCXh4LT5rZXluYW1lPSBzdHJkdXBBMlcoIjxzaG91bGRfbm90X2FwcGVhcl9hbnl3aGVyZT4iKTsKCglBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwoJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiXFxTT0ZUV0FSRVxcQ2xhc3NlcyIsJmNsX3JfaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQlmcHJpbnRmKHN0ZGVyciwiY291bGRuJ3QgY3JlYXRlIEhLRVlfTE9DQUxfTUFDSElORVxcU09GVFdBUkVcXENsYXNzZXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIpOwoJCWV4aXQoMSk7Cgl9CglrZXlfY2xhc3Nlc19yb290ID0gbG9va3VwX2hrZXkoY2xfcl9oa2V5KTsKCglBRERfUk9PVF9LRVkoa2V5X3VzZXJzKTsKCiNpZiAwCgkvKiBGSVhNRTogbG9hZCBhbGwgdXNlcnMgYW5kIHRoZWlyIHJlc3AuIHB3ZC0+cHdfZGlyLy53aW5lL3VzZXIucmVnIAoJICoJICAobGF0ZXIsIHdoZW4gYSB3aW4zMiByZWdpc3RyeSBlZGl0aW5nIHRvb2wgYmVjb21lcyBhdmFpbC4pCgkgKi8KCXdoaWxlIChwd2Q9Z2V0cHdlbnQoKSkgewoJCWlmIChwd2QtPnB3X25hbWUgPT0gTlVMTCkKCQkJY29udGludWU7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KTsKCQlSZWdDbG9zZUtleShjX3VfaGtleSk7Cgl9CiNlbmRpZgoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QgJiYgcHdkLT5wd19uYW1lKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KTsKCQlrZXlfY3VycmVudF91c2VyID0gbG9va3VwX2hrZXkoY191X2hrZXkpOwoJfSBlbHNlIHsKCQlBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfdXNlcik7Cgl9CglBRERfUk9PVF9LRVkoa2V5X3BlcmZvcm1hbmNlX2RhdGEpOwoJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CglBRERfUk9PVF9LRVkoa2V5X2R5bl9kYXRhKTsKI3VuZGVmIEFERF9ST09UX0tFWQoJU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCk7Cn0KCgp2b2lkClNIRUxMX1N0YXJ0dXBSZWdpc3RyeSgpIHsKCUhLRVkJaGtleSx4aGtleT0wOwoJRklMRQkqRjsKCWNoYXIJYnVmWzIwMF0sY3B1YnVmWzIwMF07CgoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9EWU5fREFUQSwiXFxQZXJmU3RhdHNcXFN0YXREYXRhIiwmeGhrZXkpOwoJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJcXEhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtXFxDZW50cmFsUHJvY2Vzc29yIiwmaGtleSk7CiNpZmRlZiBsaW51eAoJRj1mb3BlbigiL3Byb2MvY3B1aW5mbyIsInIiKTsKCWlmIChGKSB7CgkJaW50CXByb2Nucj0tMSx4OwoJCXdoaWxlIChOVUxMIT1mZ2V0cyhidWYsMjAwLEYpKSB7CgkJCWlmIChzc2NhbmYoYnVmLCJwcm9jZXNzb3JcdDogJWQiLCZ4KSkgewoJCQkJc3ByaW50ZihidWYsIiVkIix4KTsKCQkJCWlmICh4aGtleSkKCQkJCQlSZWdDbG9zZUtleSh4aGtleSk7CgkJCQlwcm9jbnI9eDsKCQkJCVJlZ0NyZWF0ZUtleTE2KGhrZXksYnVmLCZ4aGtleSk7CgkJCX0KCQkJaWYgKHNzY2FuZihidWYsImNwdVx0XHQ6ICVzIixjcHVidWYpKSB7CgkJCQlzcHJpbnRmKGJ1ZiwiQ1BVICVzIixjcHVidWYpOwoJCQkJaWYgKHhoa2V5KQoJCQkJCVJlZ1NldFZhbHVlRXgzMkEoeGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSk7CgkJCX0KCQl9CgkJZmNsb3NlKEYpOwoJfQoJaWYgKHhoa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwojZWxzZQoJLyogRklYTUUgKi8KCVJlZ0NyZWF0ZUtleTE2KGhrZXksIjAiLCZ4aGtleSk7CglSZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiQ1BVIDM4NiIsc3RybGVuKCJDUFUgMzg2IikpOwojZW5kaWYKCVJlZ09wZW5LZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXgzMkEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93IE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCQkJCQkJCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJnhoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4MTYoeGhrZXksIkNvbXB1dGVyTmFtZSIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKzEpOwoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCX0KfQovKioqKioqKioqKioqKioqKioqKioqKioqIFNBVkUgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgUkVHSVNUUllfU0FWRV9WRVJTSU9OCTB4MDAwMDAwMDEKCi8qIFJlZ2lzdHJ5IHNhdmVmb3JtYXQ6CiAqIElmIHlvdSBjaGFuZ2UgaXQsIGluY3JlYXNlIGFib3ZlIG51bWJlciBieSAxLCB3aGljaCB3aWxsIGZsdXNoCiAqIG9sZCByZWdpc3RyeSBkYXRhYmFzZSBmaWxlcy4KICogCiAqIEdsb2JhbDoKICogCSJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiCiAqIAlzdWJrZXlzLi4uLgogKiBTdWJrZXlzOgogKiAJa2V5bmFtZQogKgkJdmFsdWVuYW1lPWxhc3Rtb2RpZmllZCx0eXBlLGRhdGEKICoJCS4uLgogKgkJc3Via2V5cwogKgkuLi4KICoga2V5bmFtZSx2YWx1ZW5hbWUsc3RyaW5nZGF0YToKICoJdGhlIHVzdWFsIGFzY2lpIGNoYXJhY3RlcnMgZnJvbSAweDAwLTB4ZmYgKHdlbGwsIG5vdCAweDAwKQogKglhbmQgXHVYWFhYIGFzIFVOSUNPREUgdmFsdWUgWFhYWCB3aXRoIFhYWFg+MHhmZgogKgkoICI9XFxcdCIgZXNjYXBlZCBpbiBcdVhYWFggZm9ybS4pCiAqIHR5cGUsbGFzdG1vZGlmaWVkOiAKICoJaW50CiAqIAogKiBGSVhNRTogZG9lc24ndCBzYXZlICdjbGFzcycgKHdoYXQgZG9lcyBpdCBtZWFuIGFueXdheT8pLCBub3IgZmxhZ3MuCiAqCiAqIFtIS0VZX0NVUlJFTlRfVVNFUlxcU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5XQogKiBTYXZlT25seVVwZGF0ZWRLZXlzPXllcwogKi8Kc3RhdGljIGludApfc2F2ZV9jaGVja190YWludGVkKExQS0VZU1RSVUNUIGxwa2V5KSB7CglpbnQJCXRhaW50ZWQ7CgoJaWYgKCFscGtleSkKCQlyZXR1cm4gMDsKCWlmIChscGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpCgkJdGFpbnRlZCA9IDE7CgllbHNlCgkJdGFpbnRlZCA9IDA7Cgl3aGlsZSAobHBrZXkpIHsKCQlpZiAoX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1YikpIHsKCQkJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkJdGFpbnRlZCA9IDE7CgkJfQoJCWxwa2V5CT0gbHBrZXktPm5leHQ7Cgl9CglyZXR1cm4gdGFpbnRlZDsKfQoKc3RhdGljIHZvaWQKX3NhdmVfVVNUUklORyhGSUxFICpGLExQV1NUUiB3c3RyLGludCBlc2NhcGVlcSkgewoJTFBXU1RSCXM7CglpbnQJZG9lc2NhcGU7CgoJaWYgKHdzdHI9PU5VTEwpCgkJcmV0dXJuOwoJcz13c3RyOwoJd2hpbGUgKCpzKSB7CgkJZG9lc2NhcGU9MDsKCQlpZiAoKnM+MHhmZikKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xuJykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmIChlc2NhcGVlcSAmJiAqcz09Jz0nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXFwnKQoJCQlmcHV0YygqcyxGKTsgLyogaWYgXFwgdGhhbiBwdXQgaXQgdHdpY2UuICovCgkJaWYgKGRvZXNjYXBlKQoJCQlmcHJpbnRmKEYsIlxcdSUwNHgiLCooKHVuc2lnbmVkIHNob3J0KilzKSk7CgkJZWxzZQoJCQlmcHV0YygqcyxGKTsKCQlzKys7Cgl9Cn0KCnN0YXRpYyBpbnQKX3NhdmVzdWJrZXkoRklMRSAqRixMUEtFWVNUUlVDVCBscGtleSxpbnQgbGV2ZWwsaW50IGFsbCkgewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpLHRhYnMsajsKCglscHhrZXkJPSBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoCSEobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVk9MQVRJTEUpICYmCgkJCShhbGwgfHwgKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpKQoJCSkgewoJCQlmb3IgKHRhYnM9bGV2ZWw7dGFicy0tOykKCQkJCWZwdXRjKCdcdCcsRik7CgkJCV9zYXZlX1VTVFJJTkcoRixscHhrZXktPmtleW5hbWUsMSk7CgkJCWZwdXRzKCJcbiIsRik7CgkJCWZvciAoaT0wO2k8bHB4a2V5LT5ucm9mdmFsdWVzO2krKykgewoJCQkJTFBLRVlWQUxVRQl2YWw9bHB4a2V5LT52YWx1ZXMraTsKCgkJCQlmb3IgKHRhYnM9bGV2ZWwrMTt0YWJzLS07KQoJCQkJCWZwdXRjKCdcdCcsRik7CgkJCQlfc2F2ZV9VU1RSSU5HKEYsdmFsLT5uYW1lLDApOwoJCQkJZnB1dGMoJz0nLEYpOwoJCQkJZnByaW50ZihGLCIlbGQsJWxkLCIsdmFsLT50eXBlLHZhbC0+bGFzdG1vZGlmaWVkKTsKCQkJCWlmICgoMTw8dmFsLT50eXBlKSAmIFVOSUNPTlZNQVNLKQoJCQkJCV9zYXZlX1VTVFJJTkcoRiwoTFBXU1RSKXZhbC0+ZGF0YSwwKTsKCQkJCWVsc2UKCQkJCQlmb3IgKGo9MDtqPHZhbC0+bGVuO2orKykKCQkJCQkJZnByaW50ZihGLCIlMDJ4IiwqKCh1bnNpZ25lZCBjaGFyKil2YWwtPmRhdGEraikpOwoJCQkJZnB1dHMoIlxuIixGKTsKCQkJfQoJCQkvKiBkZXNjZW5kIHJlY3Vyc2l2ZWx5ICovCgkJCWlmICghX3NhdmVzdWJrZXkoRixscHhrZXktPm5leHRzdWIsbGV2ZWwrMSxhbGwpKQoJCQkJcmV0dXJuIDA7CgkJfQoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglyZXR1cm4gMTsKfQoKc3RhdGljIGludApfc2F2ZXN1YnJlZyhGSUxFICpGLExQS0VZU1RSVUNUIGxwa2V5LGludCBhbGwpIHsKCWZwcmludGYoRiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkXG4iLFJFR0lTVFJZX1NBVkVfVkVSU0lPTik7Cglfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKTsKCXJldHVybiBfc2F2ZXN1YmtleShGLGxwa2V5LT5uZXh0c3ViLDAsYWxsKTsKfQoKc3RhdGljIEJPT0wzMgpfc2F2ZXJlZyhMUEtFWVNUUlVDVCBscGtleSxjaGFyICpmbixpbnQgYWxsKSB7CglGSUxFCSpGOwoKCUY9Zm9wZW4oZm4sInciKTsKCWlmIChGPT1OVUxMKSB7CgkJZnByaW50ZihzdGRkZWIsX19GSUxFX18iOl9zYXZlcmVnOkNvdWxkbid0IG9wZW4gJXMgZm9yIHdyaXRpbmc6ICVzXG4iLAoJCQlmbixzdHJlcnJvcihlcnJubykKCQkpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmICghX3NhdmVzdWJyZWcoRixscGtleSxhbGwpKSB7CgkJZmNsb3NlKEYpOwoJCXVubGluayhmbik7CgkJZnByaW50ZihzdGRkZWIsX19GSUxFX18iOl9zYXZlcmVnOkZhaWxlZCB0byBzYXZlIGtleXMsIHBlcmhhcHMgbm8gbW9yZSBkaXNrc3BhY2UgZm9yICVzP1xuIixmbik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJZmNsb3NlKEYpOwogICAgICAgIHJldHVybiBUUlVFOwp9Cgp2b2lkClNIRUxMX1NhdmVSZWdpc3RyeSgpIHsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJY2hhcglidWZbNF07CglIS0VZCWhrZXk7CglpbnQJYWxsOwoKCWFsbD0wOwoJaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJc3RyY3B5KGJ1ZiwieWVzIik7Cgl9IGVsc2UgewoJCURXT1JEIGxlbixqdW5rLHR5cGU7CgoJCWxlbj00OwoJCWlmICgJKEVSUk9SX1NVQ0NFU1MhPVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJYnVmLAoJCQkJJmxlbgoJCQkpKXx8ICh0eXBlIT1SRUdfU1opCgkJKQoJCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCWlmIChsc3RyY21waTMyQShidWYsInllcyIpKQoJCWFsbD0xOwoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpCiAgICAgICAgewogICAgICAgICAgICAgICAgY2hhciAqdG1wID0gdG1wbmFtKE5VTEwpOwoJCWZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4ocHdkLT5wd19kaXIpICsgc3RybGVuKFdJTkVfUFJFRklYKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSArIDIgKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCk7CgkJLyogY3JlYXRlIHRoZSBkaXJlY3RvcnkuIGRvbid0IGNhcmUgYWJvdXQgZXJyb3Jjb2Rlcy4gKi8KCQlta2RpcihmbiwwNzU1KTsgLyogZHJ3eHIteHIteCAqLwoJCXN0cmNhdChmbiwiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJaWYgKF9zYXZlcmVnKGtleV9jdXJyZW50X3VzZXIsdG1wLGFsbCkpIHJlbmFtZSh0bXAsZm4pOwoJCWZyZWUoZm4pOwoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgkJaWYgKF9zYXZlcmVnKGtleV9sb2NhbF9tYWNoaW5lLHRtcCxhbGwpKSByZW5hbWUodG1wLGZuKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCWZwcmludGYoc3RkZXJyLCJTSEVMTF9TYXZlUmVnaXN0cnk6ZmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlZC5cbiIsZ2V0dWlkKCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBMUEtFWVNUUlVDVApfZmluZF9vcl9hZGRfa2V5KExQS0VZU1RSVUNUIGxwa2V5LExQV1NUUiBrZXluYW1lKSB7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJbHBscGtleT0gJihscGtleS0+bmV4dHN1Yik7CglscHhrZXkJPSAqbHBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoIWxzdHJjbXAzMlcobHB4a2V5LT5rZXluYW1lLGtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwa2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJfQoJaWYgKGxweGtleT09TlVMTCkgewoJCSpscGxwa2V5ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJCW1lbXNldChscHhrZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5LT5rZXluYW1lCT0ga2V5bmFtZTsKCX0gZWxzZQoJCWZyZWUoa2V5bmFtZSk7CglyZXR1cm4gbHB4a2V5Owp9CgpzdGF0aWMgdm9pZApfZmluZF9vcl9hZGRfdmFsdWUoCglMUEtFWVNUUlVDVCBscGtleSxMUFdTVFIgbmFtZSxEV09SRCB0eXBlLExQQllURSBkYXRhLERXT1JEIGxlbiwKCURXT1JEIGxhc3Rtb2RpZmllZAopIHsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJiAKCQkJCSFsc3RyY21wMzJXKHZhbC0+bmFtZSxuYW1lKQoJCQkpCgkJCQlicmVhazsKCQl9Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0geHJlYWxsb2MoCgkJCWxwa2V5LT52YWx1ZXMsCgkJCSgrK2xwa2V5LT5ucm9mdmFsdWVzKSpzaXplb2YoS0VZVkFMVUUpCgkJKTsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCW1lbXNldCh2YWwsJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCQl2YWwtPm5hbWUgPSBuYW1lOwoJfSBlbHNlIHsKCQlpZiAobmFtZSkKCQkJZnJlZShuYW1lKTsKCX0KCWlmICh2YWwtPmxhc3Rtb2RpZmllZDxsYXN0bW9kaWZpZWQpIHsKCQl2YWwtPmxhc3Rtb2RpZmllZD1sYXN0bW9kaWZpZWQ7CgkJdmFsLT50eXBlID0gdHlwZTsKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IApfd2luZV9yZWFkX2xpbmUoRklMRSAqRixjaGFyICoqYnVmLGludCAqbGVuKSB7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCSpidWYJPSB4cmVhbGxvYygqYnVmLCpsZW4qMik7CgkJCQljdXJyZWFkCT0gKmJ1ZiArIGN1cm9mZjsKCQkJCW15bGVuCT0gKmxlbjsJLyogd2UgZmlsbGVkIHVwIHRoZSBidWZmZXIgYW5kIAoJCQkJCQkgKiBnb3QgbmV3ICcqbGVuJyBieXRlcyB0byBmaWxsCgkJCQkJCSAqLwoJCQkJKmxlbgk9ICpsZW4gKiAyOwoJCQl9IGVsc2UgewoJCQkJKnM9J1wwJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCS8qIHRocm93IGF3YXkgY29tbWVudHMgKi8KCQlpZiAoKipidWY9PScjJyB8fCAqKmJ1Zj09JzsnKSB7CgkJCWN1cnJlYWQJPSAqYnVmOwoJCQlteWxlbgk9ICpsZW47CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocykgCS8qIGdvdCBlbmQgb2YgbGluZSAqLwoJCQlicmVhazsKCX0KCXJldHVybiAxOwp9CgovKiBjb252ZXJ0cyBhIGNoYXIqIGludG8gYSBVTklDT0RFIHN0cmluZyAodXAgdG8gYSBzcGVjaWFsIGNoYXIpCiAqIGFuZCByZXR1cm5zIHRoZSBwb3NpdGlvbiBleGFjdGx5IGFmdGVyIHRoYXQgc3RyaW5nCiAqLwpzdGF0aWMgY2hhcioKX3dpbmVfcmVhZF9VU1RSSU5HKGNoYXIgKmJ1ZixMUFdTVFIgKnN0cikgewoJY2hhcgkqczsKCUxQV1NUUgl3czsKCgkvKiByZWFkIHVwIHRvICI9IiBvciAiXDAiIG9yICJcbiIgKi8KCXMJPSBidWY7CglpZiAoKnMgPT0gJz0nKSB7CgkJLyogZW1wdHkgc3RyaW5nIGlzIHRoZSB3aW4zLjEgZGVmYXVsdCB2YWx1ZShOVUxMKSovCgkJKnN0cgk9IE5VTEw7CgkJcmV0dXJuIHM7Cgl9Cgkqc3RyCT0gKExQV1NUUil4bWFsbG9jKDIqc3RybGVuKGJ1ZikrMik7Cgl3cwk9ICpzdHI7Cgl3aGlsZSAoKnMgJiYgKCpzIT0nXG4nKSAmJiAoKnMhPSc9JykpIHsKCQlpZiAoKnMhPSdcXCcpCgkJCSp3cysrPSooKHVuc2lnbmVkIGNoYXIqKXMrKyk7CgkJZWxzZSB7CgkJCXMrKzsKCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrPSdcXCc7CgkJCQlzKys7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoKnMhPSd1JykgewoJCQkJZnByaW50ZihzdGRlcnIsIl93aW5lX3JlYWRfVVNUUklORzpOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCWZwcmludGYoc3RkZXJyLCJfd2luZV9yZWFkX1VTVFJJTkc6c3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7Cgl3cwk9ICpzdHI7Cgkqc3RyCT0gc3RyZHVwVygqc3RyKTsKCWZyZWUod3MpOwoJcmV0dXJuIHM7Cn0KCnN0YXRpYyBpbnQKX3dpbmVfbG9hZHN1YmtleSgKCUZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IGxldmVsLGNoYXIgKipidWYsaW50ICpidWZsZW4saW50IG9wdGZsYWcKKSB7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWk7CgljaGFyCQkqczsKCUxQV1NUUgkJbmFtZTsKCglscGtleS0+ZmxhZ3MgfD0gb3B0ZmxhZzsKCgkvKiBnb29kLiB3ZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KCWxweGtleQk9IE5VTEw7Cgl3aGlsZSAoMSkgewoJCWk9MDtzPSpidWY7CgkJd2hpbGUgKCpzPT0nXHQnKSB7CgkJCXMrKzsKCQkJaSsrOwoJCX0KCQlpZiAoaT5sZXZlbCkgewoJCQlpZiAobHB4a2V5PT1OVUxMKSB7CgkJCQlmcHJpbnRmKHN0ZGVyciwiX2xvYWRfc3Via2V5OkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJX3dpbmVfbG9hZHN1YmtleShGLGxweGtleSxsZXZlbCsxLGJ1ZixidWZsZW4sb3B0ZmxhZyk7CgkJCWNvbnRpbnVlOwoJCX0KCQkvKiBsZXQgdGhlIGNhbGxlciBoYW5kbGUgdGhpcyBsaW5lICovCgkJaWYgKGk8bGV2ZWwgfHwgKipidWY9PSdcMCcpCgkJCXJldHVybiAxOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CgkJCQlscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJZnByaW50ZihzdGRlcnIsIl93aW5lX2xvYWRfc3Via2V5OnVuZXhwZWN0ZWQgY2hhcmFjdGVyOiAlY1xuIiwqcyk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlzKys7CgkJCQlpZiAoMiE9c3NjYW5mKHMsIiVkLCVkLCIsJnR5cGUsJmxhc3Rtb2RpZmllZCkpIHsKCQkJCQlmcHJpbnRmKHN0ZGVyciwiX3dpbmVfbG9hZF9zdWJrZXk6IGhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJaWYgKCgxPDx0eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CgkJCQkJaWYgKGRhdGEpCgkJCQkJCWxlbiA9IGxzdHJsZW4zMlcoKExQV1NUUilkYXRhKSoyKzI7CgkJCQkJZWxzZQkKCQkJCQkJbGVuID0gMDsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShscGtleSxuYW1lLHR5cGUsZGF0YSxsZW4sbGFzdG1vZGlmaWVkKTsKCQkJfQoJCX0KCQkvKiByZWFkIHRoZSBuZXh0IGxpbmUgKi8KCQlpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCQlyZXR1cm4gMTsKCX0KCXJldHVybiAxOwp9CgpzdGF0aWMgaW50Cl93aW5lX2xvYWRzdWJyZWcoRklMRSAqRixMUEtFWVNUUlVDVCBscGtleSxpbnQgb3B0ZmxhZykgewoJaW50CXZlcjsKCWNoYXIJKmJ1ZjsKCWludAlidWZsZW47CgoJYnVmPXhtYWxsb2MoMTApO2J1Zmxlbj0xMDsKCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3NjYW5mKGJ1ZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh2ZXIhPVJFR0lTVFJZX1NBVkVfVkVSU0lPTikgewoJCWRwcmludGZfcmVnKHN0ZGRlYixfX0ZJTEVfXyI6X3dpbmVfbG9hZHN1YnJlZzpPbGQgZm9ybWF0ICglZCkgcmVnaXN0cnkgZm91bmQsIGlnbm9yaW5nIGl0LiAoYnVmIHdhcyAlcykuXG4iLHZlcixidWYpOwoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGxwa2V5LDAsJmJ1ZiwmYnVmbGVuLG9wdGZsYWcpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCnN0YXRpYyB2b2lkCl93aW5lX2xvYWRyZWcoTFBLRVlTVFJVQ1QgbHBrZXksY2hhciAqZm4saW50IG9wdGZsYWcpIHsKCUZJTEUJKkY7CgoJRj1mb3BlbihmbiwicmIiKTsKCWlmIChGPT1OVUxMKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLF9fRklMRV9fIjpDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm47Cgl9CglpZiAoIV93aW5lX2xvYWRzdWJyZWcoRixscGtleSxvcHRmbGFnKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCXJldHVybjsKCX0KCWZjbG9zZShGKTsKfQoKc3RhdGljIHZvaWQKX2NvcHlfcmVnaXN0cnkoTFBLRVlTVFJVQ1QgZnJvbSxMUEtFWVNUUlVDVCB0bykgewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlqOwoJTFBLRVlWQUxVRQl2YWxmcm9tOwoKCWZyb209ZnJvbS0+bmV4dHN1YjsKCXdoaWxlIChmcm9tKSB7CgkJbHB4a2V5ID0gX2ZpbmRfb3JfYWRkX2tleSh0byxzdHJkdXBXKGZyb20tPmtleW5hbWUpKTsKCgkJZm9yIChqPTA7ajxmcm9tLT5ucm9mdmFsdWVzO2orKykgewoJCQlMUFdTVFIJbmFtZTsKCQkJTFBCWVRFCWRhdGE7CgoJCQl2YWxmcm9tID0gZnJvbS0+dmFsdWVzK2o7CgkJCW5hbWU9dmFsZnJvbS0+bmFtZTsKCQkJaWYgKG5hbWUpIG5hbWU9c3RyZHVwVyhuYW1lKTsKCQkJZGF0YT0oTFBCWVRFKW1hbGxvYyh2YWxmcm9tLT5sZW4pOwoJCQltZW1jcHkoZGF0YSx2YWxmcm9tLT5kYXRhLHZhbGZyb20tPmxlbik7CgoJCQlfZmluZF9vcl9hZGRfdmFsdWUoCgkJCQlscHhrZXksCgkJCQluYW1lLAoJCQkJdmFsZnJvbS0+dHlwZSwKCQkJCWRhdGEsCgkJCQl2YWxmcm9tLT5sZW4sCgkJCQl2YWxmcm9tLT5sYXN0bW9kaWZpZWQKCQkJKTsKCQl9CgkJX2NvcHlfcmVnaXN0cnkoZnJvbSxscHhrZXkpOwoJCWZyb20gPSBmcm9tLT5uZXh0OwoJfQp9CgovKiBXSU5ET1dTIDk1IFJFR0lTVFJZIExPQURFUiAqLwovKiAKICogU3RydWN0dXJlIG9mIGEgd2luOTUgcmVnaXN0cnkgZGF0YWJhc2UuCiAqIG1haW4gaGVhZGVyOgogKiAwIDoJIkNSRUciCS0gbWFnaWMKICogNCA6CURXT1JEIHZlcnNpb24KICogOCA6CURXT1JEIG9mZnNldF9vZl9SR0RCX3BhcnQKICogMEMuLjFGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKgogKiAyMDogUkdLTl9zZWN0aW9uOgogKiAgIGhlYWRlcjoKICogCTAgOgkJIlJHS04iCS0gbWFnaWMKICogCTQuLjB4MUI6IAk/IChmaWxsIGluKQogKiAgICAgIDB4MjAgLi4uIG9mZnNldF9vZl9SR0RCX3BhcnQ6IERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZXMKICoKICogICBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmU6CiAqCTAwOiBEV09SRAktIHVua25vd24KICoJMDQ6IERXT1JECS0gdW5rbm93bgogKgkwODogRFdPUkQJLSB1bmtub3duLCBidXQgdXN1YWxseSAweEZGRkZGRkZGIG9uIHdpbjk1IHN5c3RlbXMKICoJMEM6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIFByZXZpb3VzTGV2ZWwgS2V5LgogKgkxMDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBTdWJsZXZlbCBLZXkuCiAqCTE0OiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IEtleSAob24gc2FtZSBsZXZlbCkuCiAqIERLRVA+MTg6IFdPUkQJLSBOciwgTG93IFNpZ25pZmljYW50IHBhcnQuCiAqCTFBOiBXT1JECS0gTnIsIEhpZ2ggU2lnbmlmaWNhbnQgcGFydC4KICoKICogVGhlIGRpc2sgYWRkcmVzcyBhbHdheXMgcG9pbnRzIHRvIHRoZSBuciBwYXJ0IG9mIHRoZSBwcmV2aW91cyBrZXkgZW50cnkgCiAqIG9mIHRoZSByZWZlcmVuY2VkIGtleS4gRG9uJ3QgYXNrIG1lIHdoeSwgb3IgZXZlbiBpZiBJIGdvdCB0aGlzIGNvcnJlY3QKICogZnJvbSBzdGFyaW5nIGF0IDFrZyBvZiBoZXhkdW1wcy4gKERLRVApCiAqCiAqIFRoZSBudW1iZXIgb2YgdGhlIGVudHJ5IGlzIHRoZSBsb3cgYnl0ZSBvZiB0aGUgTG93IFNpZ25pZmljYW50IFBhcnQgb3JlZAogKiB3aXRoIDB4MTAwICogKGxvdyBieXRlIG9mIHRoZSBIaWdoIFNpZ25pZmljYW50IHBhcnQpCiAqIChDIGV4cHJlc3Npb24gOiBuciA9IChuckxTICYgMHhGRikgfCAoKG5ySFMgJjB4RkYpPDw4KSkKICoKICogVGhlcmUgYXJlIHR3byBtaW5vciBjb3JyZWN0aW9ucyB0byB0aGUgcG9zaXRpb24gb2YgdGhhdCBzdHJ1Y3R1cmUuCiAqIDEuIElmIHRoZSBhZGRyZXNzIGlzIHh4eDAxNCBvciB4eHgwMTggaXQgd2lsbCBiZSBhbGlnbmVkIHRvIHh4eDAxYyBBTkQgCiAqICAgIHRoZSBES0UgcmVyZWFkIGZyb20gdGhlcmUuCiAqIDIuIElmIHRoZSBhZGRyZXNzIGlzIHh4eEZGeCBpdCB3aWxsIGJlIGFsaWduZWQgdG8gKHh4eCsxKTAwMC4KICogKEZJWE1FOiBzbGlnaHRseSBiZXR0ZXIgZXhwbGFuYXRpb24gbmVlZGVkIGhlcmUpCiAqCiAqIFJHREJfc2VjdGlvbjoKICogCTAwOgkJIlJHREIiCS0gbWFnaWMKICoJMDQ6IERXT1JECW9mZnNldCB0byBuZXh0IFJHREIgc2VjdGlvbiAocGVyaGFwcyBXT1JEKQogKgkwOC4uLjFGOgk/CiAqCTIwLi4uLi46CWRpc2sga2V5cwogKgogKiBkaXNrIGtleToKICogCTAwOiAJRFdPUkQJbmV4dGtleW9mZnNldAktIG9mZnNldCB0byB0aGUgbmV4dCBkaXNrIGtleSBzdHJ1Y3R1cmUKICoJMDg6IAlXT1JECW5yTFMJCS0gbG93IHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEE6IAlXT1JECW5ySFMJCS0gaGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBDOiAJRFdPUkQJYnl0ZXN1c2VkCS0gYnl0ZXMgdXNlZCBpbiB0aGlzIHN0cnVjdHVyZS4KICoJMTA6IAlXT1JECW5hbWVfbGVuCS0gbGVuZ3RoIG9mIG5hbWUgaW4gYnl0ZXMuIHdpdGhvdXQgXDAKICoJMTI6IAlXT1JECW5yX29mX3ZhbHVlcwktIG51bWJlciBvZiB2YWx1ZXMuCiAqCTE0OiAJY2hhcgluYW1lW25hbWVfbGVuXQktIG5hbWUgc3RyaW5nLiBObyBcMC4KICoJMTQrbmFtZV9sZW46IGRpc2sgdmFsdWVzCiAqCW5leHRrZXlvZmZzZXQ6IC4uLiBuZXh0IGRpc2sga2V5CiAqCiAqIGRpc2sgdmFsdWU6CiAqCTAwOglEV09SRAl0eXBlCQktIHZhbHVlIHR5cGUgKGhtbSwgY291bGQgYmUgV09SRCB0b28pCiAqCTA0OglEV09SRAkJCS0gdW5rbm93biwgdXN1YWxseSAwCiAqCTA4OglXT1JECW5hbWVsZW4JCS0gbGVuZ3RoIG9mIE5hbWUuIDAgbWVhbnMgbmFtZT1OVUxMCiAqCTBDOglXT1JECWRhdGFsZW4JCS0gbGVuZ3RoIG9mIERhdGEuCiAqCTEwOgljaGFyCW5hbWVbbmFtZWxlbl0JLSBuYW1lLCBubyBcMAogKgkxMCtuYW1lbGVuOiBCWVRFCWRhdGFbZGF0YWxlbl0gLSBkYXRhLCB3aXRob3V0IFwwIGlmIHN0cmluZwogKgkxMCtuYW1lbGVuK2RhdGFsZW46IG5leHQgdmFsdWVzIG9yIGRpc2sga2V5CiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKiByZXBlYXQgdW50aWwgZW5kIG9mIGZpbGUuCiAqCiAqIEZJWE1FOiB0aGlzIGRlc2NyaXB0aW9uIG5lZWRzIHNvbWUgc2VyaW91cyBoZWxwLCB5ZXMuCiAqLwoKc3RydWN0CV93OTVrZXl2YWx1ZSB7Cgl1bnNpZ25lZCBsb25nCQl0eXBlOwoJdW5zaWduZWQgc2hvcnQJCWRhdGFsZW47CgljaGFyCQkJKm5hbWU7Cgl1bnNpZ25lZCBjaGFyCQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCXgxOwoJaW50CQkJbGFzdG1vZGlmaWVkOwp9OwoKc3RydWN0IAlfdzk1a2V5IHsKCWNoYXIJCQkqbmFtZTsKCWludAkJCW5yb2Z2YWxzOwoJc3RydWN0CV93OTVrZXl2YWx1ZQkqdmFsdWVzOwoJdW5zaWduZWQgbG9uZwkJZGtlYWRkcjsKCXVuc2lnbmVkIGxvbmcgCQl4MTsKCXVuc2lnbmVkIGxvbmcgCQl4MjsKCXVuc2lnbmVkIGxvbmcgCQl4MzsKCXVuc2lnbmVkIGxvbmcgCQl4eDE7CglzdHJ1Y3QgX3c5NWtleQkJKnByZXZsdmw7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHRzdWI7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHQ7Cn07CgovKiBmYXN0IGxvb2t1cCB0YWJsZSBka2VhZGRyLT5uciAqLwpzdHJ1Y3QJX3c5NW5yMmRhIHsKCXVuc2lnbmVkIGxvbmcJCWRrZWFkZHI7Cgl1bnNpZ25lZCBsb25nCQlucjsKfTsKCgpzdGF0aWMgdm9pZApfdzk1X3dhbGtfdHJlZShMUEtFWVNUUlVDVCBscGtleSxzdHJ1Y3QgX3c5NWtleSAqa2V5KSB7CglpbnQJCWk7CglMUEtFWVNUUlVDVAlscHhrZXk7CglMUFdTVFIJCW5hbWU7CgoJd2hpbGUgKGtleSkgewoJCWlmIChrZXktPm5hbWUgPT0gTlVMTCkgewoJCQlmcHJpbnRmKHN0ZGVyciwiX3c5NV93YWxrX3RyZWU6UGxlYXNlIHJlcG9ydDoga2V5IHdpdGggZGtlYWRkciAlbHggbm90IGxvYWRlZCwgc2tpcHBpbmcgaGllcmFyY2h5XG4iLAoJCQkJa2V5LT5ka2VhZGRyCgkJCSk7CgkJCXJldHVybjsKCQl9CgkJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksc3RyZHVwQTJXKGtleS0+bmFtZSkpOwoKCQlpZiAoa2V5LT5ucm9mdmFsczwwKSB7CgkJCS8qIHNob3VsZG4ndCBoYXBwZW4gKi8KCQkJZnByaW50ZihzdGRlcnIsImtleSAlcyBhbHJlYWR5IHByb2Nlc3NlZCFcbiIsa2V5LT5uYW1lKTsKCQkJa2V5ID0ga2V5LT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJZm9yIChpPTA7aTxrZXktPm5yb2Z2YWxzO2krKykgewoJCQlMUEJZVEUJZGF0YTsKCQkJaW50CWxlbjsKCgkJCW5hbWUgPSBzdHJkdXBBMlcoa2V5LT52YWx1ZXNbaV0ubmFtZSk7CgkJCWlmICghKm5hbWUpIG5hbWUgPSBOVUxMOwoJCQlmcmVlKGtleS0+dmFsdWVzW2ldLm5hbWUpOwoKCQkJbGVuCT0ga2V5LT52YWx1ZXNbaV0uZGF0YWxlbjsKCQkJZGF0YQk9IGtleS0+dmFsdWVzW2ldLmRhdGE7CgkJCWlmICgoMTw8a2V5LT52YWx1ZXNbaV0udHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJZGF0YSA9IChCWVRFKilzdHJkdXBBMlcoZGF0YSk7CgkJCQlsZW4gID0gbHN0cmxlbjMyVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCWZyZWUoa2V5LT52YWx1ZXNbaV0uZGF0YSk7CgkJCX0KCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkJbHB4a2V5LAoJCQkJbmFtZSwKCQkJCWtleS0+dmFsdWVzW2ldLnR5cGUsCgkJCQlkYXRhLAoJCQkJbGVuLAoJCQkJa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkCgkJCSk7CgkJfQoJCWlmIChrZXktPnZhbHVlcykgewoJCQlmcmVlKGtleS0+dmFsdWVzKTsKCQkJa2V5LT52YWx1ZXMgPSBOVUxMOwoJCX0KCQlrZXktPm5yb2Z2YWxzPS1rZXktPm5yb2Z2YWxzLTE7CgkJX3c5NV93YWxrX3RyZWUobHB4a2V5LGtleS0+bmV4dHN1Yik7CgkJa2V5PWtleS0+bmV4dDsKCX0KfQoKLyogc21hbGwgaGVscGVyIGZ1bmN0aW9uIHRvIGFkanVzdCBhZGRyZXNzIG9mZnNldCAoZGtlYWRkcnMpICovCnN0YXRpYyB1bnNpZ25lZCBsb25nCl93OTVfYWRqX2RhKHVuc2lnbmVkIGxvbmcgZGtlYWRkcikgewoJaWYgKChka2VhZGRyJjB4RkZGKTwweDAxOCkgewoJCWludAlkaWZmOwoKCQlkaWZmPTB4MUMtKGRrZWFkZHImMHhGRkYpOwoJCXJldHVybiBka2VhZGRyK2RpZmY7Cgl9CglpZiAoKChka2VhZGRyKzB4MUMpJjB4RkZGKTwweDFDKSB7CgkJLyogcmVhZGp1c3QgdG8gMHgwMDAsCgkJICogYnV0IE9OTFkgaWYgd2UgYXJlID4weDEwMDAgYWxyZWFkeQoJCSAqLwoJCWlmIChka2VhZGRyICYgfjB4RkZGKQoJCQlyZXR1cm4gZGtlYWRkciAmIH4weEZGRjsKCX0KCXJldHVybiBka2VhZGRyOwp9CgpzdGF0aWMgaW50Cl93OTVka2Vjb21wKHN0cnVjdCBfdzk1bnIyZGEgKmEsc3RydWN0IF93OTVucjJkYSAqYil7cmV0dXJuIGEtPmRrZWFkZHItYi0+ZGtlYWRkcjt9CgpzdGF0aWMgc3RydWN0IF93OTVrZXkqCl93OTVka2Vsb29rdXAodW5zaWduZWQgbG9uZyBka2VhZGRyLGludCBuLHN0cnVjdCBfdzk1bnIyZGEgKm5yMmRhLHN0cnVjdCBfdzk1a2V5ICprZXlzKSB7CglpbnQJaSxvZmY7CgoJaWYgKGRrZWFkZHIgPT0gMHhGRkZGRkZGRikKCQlyZXR1cm4gTlVMTDsKCWlmIChka2VhZGRyPDB4MjApCgkJcmV0dXJuIE5VTEw7Cglka2VhZGRyPV93OTVfYWRqX2RhKGRrZWFkZHIrMHgxYyk7CglvZmYgPSAoZGtlYWRkci0weDNjKS8weDFjOwoJZm9yIChpPTA7aTxuO2krKykKCQlpZiAobnIyZGFbKGkrb2ZmKSVuXS5ka2VhZGRyID09IGRrZWFkZHIpCgkJCXJldHVybiBrZXlzK25yMmRhWyhpK29mZiklbl0ubnI7CgkvKiAweDNDIGhhcHBlbnMgb2Z0ZW4sIGp1c3QgcmVwb3J0IHVudXN1YWwgdmFsdWVzICovCglpZiAoZGtlYWRkciE9MHgzYykKCQlkcHJpbnRmX3JlZyhzdGRkZWIsInNlYXJjaCBoYXNuJ3QgZm91bmQgZGtlYWRkciAlbHg/XG4iLGRrZWFkZHIpOwoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkCl93OTVfbG9hZHJlZyhjaGFyKiBmbixMUEtFWVNUUlVDVCBscGtleSkgewoJLyogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlIChSR0tOIHBhcnQpICovCglzdHJ1Y3QJZGtlIHsKCQl1bnNpZ25lZCBsb25nCQl4MTsKCQl1bnNpZ25lZCBsb25nCQl4MjsKCQl1bnNpZ25lZCBsb25nCQl4MzsvKnVzdWFsbHkgMHhGRkZGRkZGRiAqLwoJCXVuc2lnbmVkIGxvbmcJCXByZXZsdmw7CgkJdW5zaWduZWQgbG9uZwkJbmV4dHN1YjsKCQl1bnNpZ25lZCBsb25nCQluZXh0OwoJCXVuc2lnbmVkIHNob3J0CQluckxTOwoJCXVuc2lnbmVkIHNob3J0CQluck1TOwoJfTsKCS8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCkgKi8KCXN0cnVjdAlka2ggewoJCXVuc2lnbmVkIGxvbmcJCW5leHRrZXlvZmY7IAoJCXVuc2lnbmVkIHNob3J0CQluckxTOwoJCXVuc2lnbmVkIHNob3J0CQluck1TOwoJCXVuc2lnbmVkIGxvbmcJCWJ5dGVzdXNlZDsKCQl1bnNpZ25lZCBzaG9ydAkJa2V5bmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsdWVzOwoJCXVuc2lnbmVkIGxvbmcJCXh4MTsKCQkvKiBrZXluYW1lICovCgkJLyogZGlzayBrZXkgdmFsdWVzIG9yIG5vdGhpbmcgKi8KCX07CgkvKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUgKi8KCXN0cnVjdAlka3YgewoJCXVuc2lnbmVkIGxvbmcJCXR5cGU7CgkJdW5zaWduZWQgbG9uZwkJeDE7CgkJdW5zaWduZWQgc2hvcnQJCXZhbG5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbGRhdGFsZW47CgkJLyogdmFsbmFtZSwgdmFsZGF0YSAqLwoJfTsKCXN0cnVjdAlfdzk1bnIyZGEgCSpucjJkYTsKCglIRklMRQkJaGZkOwoJaW50CQlsYXN0bW9kaWZpZWQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJbnIscG9zLGksd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQsb2ZmX25leHRfcmdkYjsKCXN0cnVjdAlfdzk1a2V5CSprZXlzOwoJaW50CQlucm9mZGtlczsKCXVuc2lnbmVkIGNoYXIJKmRhdGEsKmN1cmRhdGEsKm5leHRyZ2RiOwoJT0ZTVFJVQ1QJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZkaW5mbzsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIkxvYWRpbmcgV2luOTUgcmVnaXN0cnkgZGF0YWJhc2UgJyVzJ1xuIixmbik7CgloZmQ9T3BlbkZpbGUoZm4sJm9mcyxPRl9SRUFEKTsKCWlmIChoZmQ9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCW1hZ2ljWzRdPTA7CglpZiAoNCE9X2xyZWFkMzIoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIkNSRUciKSkgewoJCWZwcmludGYoc3RkZGViLCIlcyBpcyBub3QgYSB3OTUgcmVnaXN0cnkuXG4iLGZuKTsKCQlyZXR1cm47Cgl9CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZ2ZXJzaW9uLDQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQzMihoZmQsJnJnZGJzZWN0aW9uLDQpKQoJCXJldHVybjsKCWlmICgtMT09X2xsc2VlayhoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJSR0tOIikpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJXNcbiIsbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrKGhmZCwweDQwLFNFRUtfU0VUKSkKCQlyZXR1cm47Cgl3aGVyZQk9IDB4NDA7CgllbmQJPSByZ2Ric2VjdGlvbjsKCglucm9mZGtlcyA9IChlbmQtd2hlcmUpL3NpemVvZihzdHJ1Y3QgZGtlKSsxMDA7CglkYXRhID0gKGNoYXIqKXhtYWxsb2MoZW5kLXdoZXJlKTsKCWlmICgoZW5kLXdoZXJlKSE9X2xyZWFkMzIoaGZkLGRhdGEsZW5kLXdoZXJlKSkKCQlyZXR1cm47CgljdXJkYXRhID0gZGF0YTsKCglrZXlzID0gKHN0cnVjdCBfdzk1a2V5Kil4bWFsbG9jKG5yb2Zka2VzICogc2l6ZW9mKHN0cnVjdCBfdzk1a2V5KSk7CgltZW1zZXQoa2V5cywnXDAnLG5yb2Zka2VzKnNpemVvZihzdHJ1Y3QgX3c5NWtleSkpOwoJbnIyZGE9IChzdHJ1Y3QgX3c5NW5yMmRhKil4bWFsbG9jKG5yb2Zka2VzICogc2l6ZW9mKHN0cnVjdCBfdzk1bnIyZGEpKTsKCW1lbXNldChucjJkYSwnXDAnLG5yb2Zka2VzKnNpemVvZihzdHJ1Y3QgX3c5NW5yMmRhKSk7CgoJZm9yIChpPTA7aTxucm9mZGtlcztpKyspIHsKCQlzdHJ1Y3QJZGtlCWRrZTsKCQl1bnNpZ25lZCBsb25nIAlka2VhZGRyOwoKCQlwb3M9Y3VyZGF0YS1kYXRhKzB4NDA7CgkJbWVtY3B5KCZka2UsY3VyZGF0YSxzaXplb2YoZGtlKSk7CgkJY3VyZGF0YSs9c2l6ZW9mKGRrZSk7CgkJbnIgPSBka2UubnJMUyArIChka2UubnJNUzw8OCk7CgkJZGtlYWRkcj1wb3MtNDsKCQlpZiAoKGRrZWFkZHImMHhGRkYpPDB4MDE4KSB7CgkJCWludAlkaWZmOwoKCQkJZGlmZj0weDFDLShka2VhZGRyJjB4RkZGKTsKCQkJZGtlYWRkcis9ZGlmZjsKCQkJY3VyZGF0YSs9ZGlmZi1zaXplb2YoZGtlKTsKCQkJbWVtY3B5KCZka2UsY3VyZGF0YSxzaXplb2YoZGtlKSk7CgkJCW5yID0gZGtlLm5yTFMgKyAoZGtlLm5yTVM8PDgpOwoJCQljdXJkYXRhKz1zaXplb2YoZGtlKTsKCQl9CgkJaWYgKCgoZGtlYWRkcisweDFDKSYweEZGRik8MHgxQykgewoJCQkvKiByZWFkanVzdCB0byAweDAwMCwKCQkJICogYnV0IE9OTFkgaWYgd2UgYXJlID4weDEwMDAgYWxyZWFkeQoJCQkgKi8KCQkJaWYgKGRrZWFkZHIgJiB+MHhGRkYpCgkJCQlka2VhZGRyID0gZGtlYWRkciAmIH4weEZGRjsKCQl9CgkJaWYgKG5yPm5yb2Zka2VzKSB7CgkJCS8qIDB4RkZGRkZGRkYgaGFwcGVucyBvZnRlbiwganVzdCByZXBvcnQgdW51c3VhbCB2YWx1ZXMgKi8KCQkJaWYgKG5yIT0weEZGRkZGRkZGKQoJCQkJZHByaW50Zl9yZWcoc3RkZGViLCJuciAlbGQgZXhjZWVkcyBucm9mZGtlcyAlZCwgc2tpcHBpbmcuXG4iLG5yLG5yb2Zka2VzKTsKCQkJY29udGludWU7CgkJfQoJCWlmIChrZXlzW25yXS5ka2VhZGRyKSB7CgkJCWludAl4OwoKCQkJZm9yICh4PXNpemVvZihka2UpO3gtLTspCgkJCQlpZiAoKChjaGFyKikmZGtlKVt4XSkKCQkJCQlicmVhazsKCQkJaWYgKHg9PS0xKQoJCQkJYnJlYWs7IC8qIGZpbmlzaGVkIHJlYWRpbmcgaWYgd2UgZ290IG9ubHkgMCAqLwoJCQlpZiAobnIpIHsKCQkJCWlmICgJKGRrZS5uZXh0IT0obG9uZylrZXlzW25yXS5uZXh0KQl8fAoJCQkJCShka2UubmV4dHN1YiE9KGxvbmcpa2V5c1tucl0ubmV4dHN1YikJfHwKCQkJCQkoZGtlLnByZXZsdmwhPShsb25nKWtleXNbbnJdLnByZXZsdmwpIAoJCQkJKQoJCQkJCWRwcmludGZfcmVnKHN0ZGRlYiwia2V5IGRvdWJsZWQ/IG5yPSVsZCxrZXktPmRrZWFkZHI9JWx4LGRrZWFkZHI9JWx4XG4iLG5yLGtleXNbbnJdLmRrZWFkZHIsZGtlYWRkcik7CgkJCX0KCQkJY29udGludWU7CgkJfQoJCW5yMmRhW2ldLm5yCSA9IG5yOwoJCW5yMmRhW2ldLmRrZWFkZHIgPSBka2VhZGRyOwoKCQlrZXlzW25yXS5ka2VhZGRyID0gZGtlYWRkcjsKCQlrZXlzW25yXS54MSA9IGRrZS54MTsKCQlrZXlzW25yXS54MiA9IGRrZS54MjsKCQlrZXlzW25yXS54MyA9IGRrZS54MzsKCQlrZXlzW25yXS5wcmV2bHZsPSAoc3RydWN0IF93OTVrZXkqKWRrZS5wcmV2bHZsOwoJCWtleXNbbnJdLm5leHRzdWI9IChzdHJ1Y3QgX3c5NWtleSopZGtlLm5leHRzdWI7CgkJa2V5c1tucl0ubmV4dCAJPSAoc3RydWN0IF93OTVrZXkqKWRrZS5uZXh0OwoJfQoJZnJlZShkYXRhKTsKCglxc29ydChucjJkYSxucm9mZGtlcyxzaXplb2YobnIyZGFbMF0pLAogICAgICAgICAgICAgIChpbnQoKikoY29uc3Qgdm9pZCAqLGNvbnN0IHZvaWQqKSlfdzk1ZGtlY29tcCk7CgoJLyogU1RFUCAyOiBrZXlkYXRhICYgdmFsdWVzICovCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmZCwmaGZkaW5mbykpCgkJcmV0dXJuOwoJZW5kCQk9IGhmZGluZm8ubkZpbGVTaXplTG93OwoJbGFzdG1vZGlmaWVkCT0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCYoaGZkaW5mby5mdExhc3RXcml0ZVRpbWUpKTsKCglpZiAoLTE9PV9sbHNlZWsoaGZkLHJnZGJzZWN0aW9uLFNFRUtfU0VUKSkKCQlyZXR1cm47CglkYXRhID0gKGNoYXIqKXhtYWxsb2MoZW5kLXJnZGJzZWN0aW9uKTsKCWlmICgoZW5kLXJnZGJzZWN0aW9uKSE9X2xyZWFkMzIoaGZkLGRhdGEsZW5kLXJnZGJzZWN0aW9uKSkKCQlyZXR1cm47CglfbGNsb3NlKGhmZCk7CgljdXJkYXRhID0gZGF0YTsKCW1lbWNweShtYWdpYyxjdXJkYXRhLDQpOwoJbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCW5leHRyZ2RiID0gY3VyZGF0YStvZmZfbmV4dF9yZ2RiOwoJaWYgKHN0cmNtcChtYWdpYywiUkdEQiIpKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJ0aGlyZCBJRkYgaGVhZGVyIG5vdCBSR0RCLCBidXQgJXNcbiIsbWFnaWMpOwoJCXJldHVybjsKCX0KCWN1cmRhdGE9ZGF0YSsweDIwOwoJd2hpbGUgKDEpIHsKCQlzdHJ1Y3QJZGtoIGRraDsKCQlpbnQJYnl0ZXNyZWFkOwoJCXN0cnVjdAlfdzk1a2V5CSprZXkseGtleTsKCgkJYnl0ZXNyZWFkID0gMDsKCQlpZiAoY3VyZGF0YT49bmV4dHJnZGIpIHsKCQkJY3VyZGF0YSA9IG5leHRyZ2RiOwoJCQlpZiAoIXN0cm5jbXAoY3VyZGF0YSwiUkdEQiIsNCkpIHsKCQkJCW1lbWNweSgmb2ZmX25leHRfcmdkYixjdXJkYXRhKzQsNCk7CgkJCQluZXh0cmdkYiA9IGN1cmRhdGErb2ZmX25leHRfcmdkYjsKCQkJCWN1cmRhdGErPTB4MjA7CgkJCX0gZWxzZSB7CgkJCQlkcHJpbnRmX3JlZyhzdGRkZWIsImF0IGVuZCBvZiBSR0RCIHNlY3Rpb24sIGJ1dCBubyBuZXh0IGhlYWRlciAoJXggb2YgJWx4KS4gQnJlYWtpbmcuXG4iLGN1cmRhdGEtZGF0YSxlbmQtcmdkYnNlY3Rpb24pOwoJCQkJYnJlYWs7CgkJCX0KCQl9CiNkZWZpbmUgWFJFQUQod2hlcmV0byxsZW4pIFwKCWlmICgoY3VyZGF0YS1kYXRhK2xlbik8ZW5kKSB7XAoJCW1lbWNweSh3aGVyZXRvLGN1cmRhdGEsbGVuKTtcCgkJY3VyZGF0YSs9bGVuO1wKCQlieXRlc3JlYWQrPWxlbjtcCgl9CgoJCVhSRUFEKCZka2gsc2l6ZW9mKGRraCkpOwoJCW5yID0gZGtoLm5yTFMgKyAoZGtoLm5yTVM8PDgpOwoJCWlmICgobnI+bnJvZmRrZXMpIHx8IChka2gubnJMUyA9PSAweEZGRkYpKSB7CgkJCWlmIChka2gubnJMUyA9PSAweEZGRkYpIHsKCQkJCS8qIHNraXAgb3ZlciBrZXkgdXNpbmcgbmV4dGtleW9mZiAqLwogCQkJCWN1cmRhdGErPWRraC5uZXh0a2V5b2ZmLXNpemVvZihzdHJ1Y3QgZGtoKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiaGF2ZW4ndCBmb3VuZCBuciAlbGQuXG4iLG5yKTsKCQkJa2V5ID0gJnhrZXk7CgkJCW1lbXNldChrZXksJ1wwJyxzaXplb2YoeGtleSkpOwoJCX0gZWxzZSB7CgkJCWtleSA9IGtleXMrbnI7CgkJCWlmICgha2V5LT5ka2VhZGRyKQoJCQkJZHByaW50Zl9yZWcoc3RkZGViLCJrZXkgd2l0aCBucj0lbGQgaGFzIG5vIGRrZWFkZHI/XG4iLG5yKTsKCQl9CgkJa2V5LT5ucm9mdmFscwk9IGRraC52YWx1ZXM7CgkJa2V5LT5uYW1lCT0gKGNoYXIqKXhtYWxsb2MoZGtoLmtleW5hbWVsZW4rMSk7CgkJa2V5LT54eDEJPSBka2gueHgxOwoJCVhSRUFEKGtleS0+bmFtZSxka2gua2V5bmFtZWxlbik7CgkJa2V5LT5uYW1lW2RraC5rZXluYW1lbGVuXT0wOwoJCWlmIChrZXktPm5yb2Z2YWxzKSB7CgkJCWtleS0+dmFsdWVzID0gKHN0cnVjdCBfdzk1a2V5dmFsdWUqKXhtYWxsb2MoCgkJCQlzaXplb2Yoc3RydWN0IF93OTVrZXl2YWx1ZSkqa2V5LT5ucm9mdmFscwoJCQkpOwoJCQlmb3IgKGk9MDtpPGtleS0+bnJvZnZhbHM7aSsrKSB7CgkJCQlzdHJ1Y3QJZGt2CWRrdjsKCgkJCQlYUkVBRCgmZGt2LHNpemVvZihka3YpKTsKCQkJCWtleS0+dmFsdWVzW2ldLnR5cGUgPSBka3YudHlwZTsKCQkJCWtleS0+dmFsdWVzW2ldLm5hbWUgPSAoY2hhciopeG1hbGxvYygKCQkJCQlka3YudmFsbmFtZWxlbisxCgkJCQkpOwoJCQkJa2V5LT52YWx1ZXNbaV0uZGF0YWxlbiA9IGRrdi52YWxkYXRhbGVuOwoJCQkJa2V5LT52YWx1ZXNbaV0uZGF0YSA9ICh1bnNpZ25lZCBjaGFyKil4bWFsbG9jKAoJCQkJCWRrdi52YWxkYXRhbGVuKzEKCQkJCSk7CgkJCQlrZXktPnZhbHVlc1tpXS54MSAgID0gZGt2LngxOwoJCQkJWFJFQUQoa2V5LT52YWx1ZXNbaV0ubmFtZSxka3YudmFsbmFtZWxlbik7CgkJCQlYUkVBRChrZXktPnZhbHVlc1tpXS5kYXRhLGRrdi52YWxkYXRhbGVuKTsKCQkJCWtleS0+dmFsdWVzW2ldLmRhdGFbZGt2LnZhbGRhdGFsZW5dPTA7CgkJCQlrZXktPnZhbHVlc1tpXS5uYW1lW2Rrdi52YWxuYW1lbGVuXT0wOwoJCQkJa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQkJfQoJCX0KCQlpZiAoYnl0ZXNyZWFkICE9IGRraC5uZXh0a2V5b2ZmKSB7CgkJCWlmIChka2guYnl0ZXN1c2VkICE9IGJ5dGVzcmVhZCkKCQkJCWRwcmludGZfcmVnKHN0ZGRlYiwKCQkJCQkicmVhZCBoYXMgZGlmZmVyZW5jZSBpbiByZWFkIGJ5dGVzICglZCkgYW5kIG5leHRvZmZzZXQgKCVsZCkgKGJ5dGVzdXNlZD0lbGQpXG4iLGJ5dGVzcmVhZCxka2gubmV4dGtleW9mZiwKCQkJCQlka2guYnl0ZXN1c2VkCgkJCQkpOwoJCQljdXJkYXRhICs9IGRraC5uZXh0a2V5b2ZmLWJ5dGVzcmVhZDsKCQl9CgkJa2V5LT5wcmV2bHZsCT0gX3c5NWRrZWxvb2t1cCgobG9uZylrZXktPnByZXZsdmwsbnJvZmRrZXMsbnIyZGEsa2V5cyk7CgkJa2V5LT5uZXh0c3ViCT0gX3c5NWRrZWxvb2t1cCgobG9uZylrZXktPm5leHRzdWIsbnJvZmRrZXMsbnIyZGEsa2V5cyk7CgkJa2V5LT5uZXh0CT0gX3c5NWRrZWxvb2t1cCgobG9uZylrZXktPm5leHQsbnJvZmRrZXMsbnIyZGEsa2V5cyk7CgkJaWYgKCFieXRlc3JlYWQpCgkJCWJyZWFrOwoJfQoJZnJlZShkYXRhKTsKCV93OTVfd2Fsa190cmVlKGxwa2V5LGtleXMpOwoJZnJlZShrZXlzKTsKfQoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUxQS0VZU1RSVUNUCWxwa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CglMUEtFWVNUUlVDVAkJeGxwa2V5OwoJTFBXU1RSCQkJbmFtZSx2YWx1ZTsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcDMyQSh0YWlsLCIuY2xhc3NlcyIpKSB7CgkJCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQoJCQluYW1lPVNUUklORzMyX0R1cEFuc2lUb1VuaSh0YWlsKTsKCgkJCXhscGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CgkJCQkJdmFsdWU9U1RSSU5HMzJfRHVwQW5zaVRvVW5pKHRhaWwpOwoJCQkJCV9maW5kX29yX2FkZF92YWx1ZSh4bHBrZXksTlVMTCxSRUdfU1osKExQQllURSl2YWx1ZSxsc3RybGVuMzJXKHZhbHVlKSoyKzIsbGFzdG1vZGlmaWVkKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiX193MzFfZHVtcHRyZWU6c3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHhscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9Cn0KCnZvaWQKX3czMV9sb2FkcmVnKCkgewoJSEZJTEUJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCUhLRVkJCQloa2V5OwoJTFBLRVlTVFJVQ1QJCWxwa2V5OwoKCWhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGY9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZDMyKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIl93MzFfbG9hZHJlZzpyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJfdzMxX2xvYWRyZWc6cmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkMzIoaGYsdGFiLGxlbikpIHsKCQlkcHJpbnRmX3JlZyhzdGRlcnIsIl93MzFfbG9hZHJlZzpjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJZHByaW50Zl9yZWcoc3RkZXJyLCJfdzMxX2xvYWRyZWc6Y291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAoaGVhZC50ZXh0c2l6ZSE9X2xyZWFkMzIoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJZHByaW50Zl9yZWcoc3RkZXJyLCJfdzMxX2xvYWRyZWc6dGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlkcHJpbnRmX3JlZyhzdGRlcnIsIl93MzFfbG9hZHJlZzpHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkCT0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCYoaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSkpOwoKCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcU09GVFdBUkVcXENsYXNzZXMiLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykKCQlyZXR1cm47CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZShoZik7CglyZXR1cm47Cn0KCnZvaWQKU0hFTExfTG9hZFJlZ2lzdHJ5KCkgewoJY2hhcgkqZm47CglzdHJ1Y3QJcGFzc3dkCSpwd2Q7CglMUEtFWVNUUlVDVAlscGtleTsKCUhLRVkJCWhrZXk7CgoKCWlmIChrZXlfY2xhc3Nlc19yb290PT1OVUxMKQoJCVNIRUxMX0luaXQoKTsKCgkvKiBMb2FkIHdpbmRvd3MgMy4xIGVudHJpZXMgKi8KCV93MzFfbG9hZHJlZygpOwoJLyogTG9hZCB3aW5kb3dzIDk1IGVudHJpZXMgKi8KCV93OTVfbG9hZHJlZygiQzpcXHN5c3RlbS4xc3QiLAlrZXlfbG9jYWxfbWFjaGluZSk7Cglfdzk1X2xvYWRyZWcoInN5c3RlbS5kYXQiLAlrZXlfbG9jYWxfbWFjaGluZSk7Cglfdzk1X2xvYWRyZWcoInVzZXIuZGF0IiwJa2V5X3VzZXJzKTsKCgkvKiB0aGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBpcyBsb2FkZWQgdW5kZXIgSEtFWV9VU0VSU1xcLkRlZmF1bHQgKi8KCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleSk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJX3dpbmVfbG9hZHJlZyhscGtleSxTQVZFX1VTRVJTX0RFRkFVTFQsMCk7CgoJLyogSEtFWV9VU0VSU1xcLkRlZmF1bHQgaXMgY29waWVkIHRvIEhLRVlfQ1VSUkVOVF9VU0VSICovCglfY29weV9yZWdpc3RyeShscGtleSxrZXlfY3VycmVudF91c2VyKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyAqLwoJX3dpbmVfbG9hZHJlZyhrZXlfbG9jYWxfbWFjaGluZSxTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVCwwKTsKCgkvKiBsb2FkIHRoZSB1c2VyIHNhdmVkIHJlZ2lzdHJpZXMgKi8KCgkvKiBGSVhNRTogdXNlIGdldGVudigiSE9NRSIpIG9yIGdldHB3dWlkKGdldHVpZCgpKS0+cHdfZGlyID8/ICovCgoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpIHsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKCQlfd2luZV9sb2FkcmVnKGtleV9jdXJyZW50X3VzZXIsZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCV93aW5lX2xvYWRyZWcoa2V5X2xvY2FsX21hY2hpbmUsZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCWZwcmludGYoc3RkZXJyLCJTSEVMTF9Mb2FkUmVnaXN0cnk6ZmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlZC5cbiIsZ2V0dWlkKCkpOwoJaWYgKEVSUk9SX1NVQ0NFU1M9PVJlZ0NyZWF0ZUtleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkpIHsKCQlEV09SRAlqdW5rLHR5cGUsbGVuOwoJCWNoYXIJZGF0YVs1XTsKCgkJbGVuPTQ7CgkJaWYgKCgJUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCQkJaGtleSwKCQkJCVZBTF9TQVZFVVBEQVRFRCwKCQkJCSZqdW5rLAoJCQkJJnR5cGUsCgkJCQlkYXRhLAoJCQkJJmxlbgoJCQkpIT1FUlJPUl9TVUNDRVNTKSB8fAoJCQl0eXBlICE9IFJFR19TWgoJCSkKCQkJUmVnU2V0VmFsdWVFeDMyQShoa2V5LFZBTF9TQVZFVVBEQVRFRCwwLFJFR19TWiwieWVzIiw0KTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIE9wZW4gS2V5cy4KICoKICogQWxsIGZ1bmN0aW9ucyBhcmUgc3R1YnMgdG8gUmVnT3BlbktleUV4MzJXIHdoZXJlIGFsbCB0aGUKICogbWFnaWMgaGFwcGVucy4gCiAqCiAqIEZJWE1FOiBzZWN1cml0eSxvcHRpb25zLGRlc2lyZWRhY2Nlc3MsLi4uCiAqCiAqIENhbGxwYXRoOgogKiBSZWdPcGVuS2V5MTYgLT4gUmVnT3BlbktleTMyQSAtPiBSZWdPcGVuS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdPcGVuS2V5MzJXICAgLT4gUmVnT3BlbktleUV4MzJXIAogKi8KCi8qIFJlZ09wZW5LZXlFeFcJCVtBRFZBUEkzMi4xNTBdICovCkRXT1JEIFJlZ09wZW5LZXlFeDMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCURXT1JECWR3UmVzZXJ2ZWQsCglSRUdTQU0Jc2FtRGVzaXJlZCwKCUxQSEtFWQlyZXRrZXkKKSB7CglMUEtFWVNUUlVDVAlscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnT3BlbktleUV4MzJXKCVseCwlcywlbGQsJWx4LCVwKVxuIiwKCQkoTE9ORyloa2V5LFcyQyhscHN6U3ViS2V5LDApLGR3UmVzZXJ2ZWQsc2FtRGVzaXJlZCxyZXRrZXkKCSk7CgoJbHBOZXh0S2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwTmV4dEtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewoJCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCQkqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CgkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cgl9CglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgCT0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAoaTx3cGMpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgkJfQoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CgkqcmV0a2V5CT0gY3VycmVudGhhbmRsZTsKCUZSRUVfS0VZX1BBVEg7CglyZXR1cm4JU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnT3BlbktleVcJCQlbQURWQVBJMzIuMTUxXSAqLwpEV09SRCBSZWdPcGVuS2V5MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnT3BlbktleTMyVyglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksVzJDKGxwc3pTdWJLZXksMCkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ09wZW5LZXlFeDMyVyhoa2V5LGxwc3pTdWJLZXksMCxLRVlfQUxMX0FDQ0VTUyxyZXRrZXkpOwp9CgoKLyogUmVnT3BlbktleUV4QQkJW0FEVkFQSTMyLjE0OV0gKi8KRFdPUkQgUmVnT3BlbktleUV4MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1Jlc2VydmVkLAoJUkVHU0FNCXNhbURlc2lyZWQsCglMUEhLRVkJcmV0a2V5CikgewoJTFBXU1RSCWxwc3pTdWJLZXlXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnT3BlbktleUV4MzJBKCVseCwlcywlbGQsJWx4LCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXksZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleQoJKTsKCWlmIChscHN6U3ViS2V5KQoJCWxwc3pTdWJLZXlXPXN0cmR1cEEyVyhscHN6U3ViS2V5KTsKCWVsc2UKCQlscHN6U3ViS2V5Vz1OVUxMOwoJcmV0PVJlZ09wZW5LZXlFeDMyVyhoa2V5LGxwc3pTdWJLZXlXLGR3UmVzZXJ2ZWQsc2FtRGVzaXJlZCxyZXRrZXkpOwoJaWYgKGxwc3pTdWJLZXlXKQoJCWZyZWUobHBzelN1YktleVcpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnT3BlbktleUEJCQlbQURWQVBJMzIuMTQ4XSAqLwpEV09SRCBSZWdPcGVuS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5MzJBKCVseCwlcywlcClcbiIsCgkJKExPTkcpaGtleSxscHN6U3ViS2V5LHJldGtleQoJKTsKCXJldHVybglSZWdPcGVuS2V5RXgzMkEoaGtleSxscHN6U3ViS2V5LDAsS0VZX0FMTF9BQ0NFU1MscmV0a2V5KTsKfQoKLyogUmVnT3BlbktleQkJCVtTSEVMTC4xXSBbS0VSTkVMLjIxN10gKi8KRFdPUkQgUmVnT3BlbktleTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5MTYoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ09wZW5LZXkzMkEoaGtleSxscHN6U3ViS2V5LHJldGtleSk7Cn0KCi8qIAogKiBDcmVhdGUga2V5cwogKiAKICogQWxsIHRob3NlIGZ1bmN0aW9ucyBjb252ZXJ0IHRoZWlyIHJlc3BlY3RpdmUgCiAqIGFyZ3VtZW50cyBhbmQgY2FsbCBSZWdDcmVhdGVLZXlFeFcgYXQgdGhlIGVuZC4KICoKICogRklYTUU6IG5vIHNlY3VyaXR5LG5vIGFjY2VzcyBhdHRyaWIsbm8gb3B0aW9uaGFuZGxpbmcgeWV0LgogKgogKiBDYWxscGF0aDoKICogUmVnQ3JlYXRlS2V5MTYgLT4gUmVnQ3JlYXRlS2V5MzJBIC0+IFJlZ0NyZWF0ZUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0NyZWF0ZUtleTMyVyAgIC0+IFJlZ0NyZWF0ZUtleUV4MzJXCiAqLwoKLyogUmVnQ3JlYXRlS2V5RXhXCQlbQURWQVBJMzIuMTMxXSAqLwpEV09SRCBSZWdDcmVhdGVLZXlFeDMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCURXT1JECWR3UmVzZXJ2ZWQsCglMUFdTVFIJbHBzekNsYXNzLAoJRFdPUkQJZmR3T3B0aW9ucywKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywKCUxQSEtFWQlyZXRrZXksCglMUERXT1JECWxwRGlzcG9zCikgewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKLypGSVhNRTogaGFuZGxlIHNlY3VyaXR5L2FjY2Vzcy93aGF0ZXZlciAqLwoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDcmVhdGVLZXlFeDMyVyglbHgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLAoJCShMT05HKWhrZXksCgkJVzJDKGxwc3pTdWJLZXksMCksCgkJZHdSZXNlcnZlZCwKCQlXMkMobHBzekNsYXNzLDEpLAoJCWZkd09wdGlvbnMsCgkJc2FtRGVzaXJlZCwKCQlscFNlY0F0dHJpYnMsCgkJcmV0a2V5LAoJCWxwRGlzcG9zCgkpOwoKCWxwTmV4dEtleQk9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscE5leHRLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKCQlhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwoJCWxwTmV4dEtleS0+ZmxhZ3N8PVJFR19PUFRJT05fVEFJTlRFRDsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KQoJCQlicmVhazsKCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJaWYgKGxweGtleSkgewoJCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwoJCWlmIChscERpc3BvcykKCQkJKmxwRGlzcG9zCT0gUkVHX09QRU5FRF9FWElTVElOR19LRVk7CgkJRlJFRV9LRVlfUEFUSDsKCQlyZXR1cm4JU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCS8qIGdvb2QuIG5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlyZXR1cm4gU0hFTExfRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJKCpscGxwUHJldktleSktPmtleW5hbWUJPSBzdHJkdXBXKHdwc1tpXSk7CgkJKCpscGxwUHJldktleSktPm5leHQJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0c3ViCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+dmFsdWVzCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bnJvZnZhbHVlcyA9IDA7CgkJKCpscGxwUHJldktleSktPmZsYWdzIAk9IFJFR19PUFRJT05fVEFJTlRFRDsKCQlpZiAobHBzekNsYXNzKQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgkJZWxzZQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBOVUxMOwoJCWxwTmV4dEtleQk9ICpscGxwUHJldktleTsKCQlpKys7Cgl9CglhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgoJLypGSVhNRTogZmxhZyBoYW5kbGluZyBjb3JyZWN0PyAqLwoJbHBOZXh0S2V5LT5mbGFncz0gZmR3T3B0aW9ucyB8UkVHX09QVElPTl9UQUlOVEVEOwoJaWYgKGxwc3pDbGFzcykKCQlscE5leHRLZXktPmNsYXNzID0gc3RyZHVwVyhscHN6Q2xhc3MpOwoJZWxzZQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBOVUxMOwoJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwoJaWYgKGxwRGlzcG9zKQoJCSpscERpc3Bvcwk9IFJFR19DUkVBVEVEX05FV19LRVk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0NyZWF0ZUtleVcJCVtBRFZBUEkzMi4xMzJdICovCkRXT1JEIFJlZ0NyZWF0ZUtleTMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCUxQSEtFWQlyZXRrZXkKKSB7CglEV09SRAlqdW5rLHJldDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0NyZWF0ZUtleTMyVyglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksVzJDKGxwc3pTdWJLZXksMCkscmV0a2V5CgkpOwoJcmV0PVJlZ0NyZWF0ZUtleUV4MzJXKAoJCWhrZXksCQkvKiBrZXkgaGFuZGxlICovCgkJbHBzelN1YktleSwJLyogc3Via2V5IG5hbWUgKi8KCQkwLAkJLyogcmVzZXJ2ZWQgPSAwICovCgkJTlVMTCwJCS8qIGxwc3pDbGFzcz8gRklYTUU6ID8gKi8KCQlSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwJLyogb3B0aW9ucyAqLwoJCUtFWV9BTExfQUNDRVNTLAkvKiBkZXNpcmVkIGFjY2VzcyBhdHRyaWJzICovCgkJTlVMTCwJCS8qIGxwc2VjdXJpdHkgYXR0cmlidXRlcyAqLwoJCXJldGtleSwJCS8qIGxwcmV0a2V5ICovCgkJJmp1bmsJCS8qIGRpc3Bvc2l0aW9uIHZhbHVlICovCgkpOwoJcmV0dXJuCXJldDsKfQoKLyogUmVnQ3JlYXRlS2V5RXhBCQlbQURWQVBJMzIuMTMwXSAqLwpEV09SRCBSZWdDcmVhdGVLZXlFeDMyQSgKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdSZXNlcnZlZCwKCUxQU1RSCWxwc3pDbGFzcywKCURXT1JECWZkd09wdGlvbnMsCglSRUdTQU0Jc2FtRGVzaXJlZCwKCUxQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsCglMUEhLRVkJcmV0a2V5LAoJTFBEV09SRAlscERpc3BvcwopIHsKCUxQV1NUUglscHN6U3ViS2V5VyxscHN6Q2xhc3NXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5RXgzMkEoJWx4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIiwKCQkoTE9ORyloa2V5LAoJCWxwc3pTdWJLZXksCgkJZHdSZXNlcnZlZCwKCQlscHN6Q2xhc3MsCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleSkKCQlscHN6U3ViS2V5Vz1zdHJkdXBBMlcobHBzelN1YktleSk7CgllbHNlCgkJbHBzelN1YktleVc9TlVMTDsKCWlmIChscHN6Q2xhc3MpCgkJbHBzekNsYXNzVz1zdHJkdXBBMlcobHBzekNsYXNzKTsKCWVsc2UKCQlscHN6Q2xhc3NXPU5VTEw7CglyZXQ9UmVnQ3JlYXRlS2V5RXgzMlcoCgkJaGtleSwKCQlscHN6U3ViS2V5VywKCQlkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleVcpCgkJZnJlZShscHN6U3ViS2V5Vyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnQ3JlYXRlS2V5QQkJW0FEVkFQSTMyLjEyOV0gKi8KRFdPUkQgUmVnQ3JlYXRlS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJRFdPUkQJanVuazsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0NyZWF0ZUtleTMyQSglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxyZXRrZXkKCSk7CglyZXR1cm4JUmVnQ3JlYXRlS2V5RXgzMkEoCgkJaGtleSwJCS8qIGtleSBoYW5kbGUgKi8KCQlscHN6U3ViS2V5LAkvKiBzdWJrZXkgbmFtZSAqLwoJCTAsCQkvKiByZXNlcnZlZCA9IDAgKi8KCQlOVUxMLAkJLyogbHBzekNsYXNzPyBGSVhNRTogPyAqLwoJCVJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLC8qIG9wdGlvbnMgKi8KCQlLRVlfQUxMX0FDQ0VTUywJLyogZGVzaXJlZCBhY2Nlc3MgYXR0cmlicyAqLwoJCU5VTEwsCQkvKiBscHNlY3VyaXR5IGF0dHJpYnV0ZXMgKi8KCQlyZXRrZXksCQkvKiBscHJldGtleSAqLwoJCSZqdW5rCQkvKiBkaXNwb3NpdGlvbiB2YWx1ZSAqLwoJKTsKfQoKLyogUmVnQ3JlYXRlS2V5CQkJW1NIRUxMLjJdIFtLRVJORUwuMjE4XSAqLwpEV09SRCBSZWdDcmVhdGVLZXkxNigKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5MTYoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ0NyZWF0ZUtleTMyQShoa2V5LGxwc3pTdWJLZXkscmV0a2V5KTsKfQoKLyogCiAqIFF1ZXJ5IFZhbHVlIEZ1bmN0aW9ucwogKiBXaW4zMiBkaWZmZXJzIGJldHdlZW4ga2V5bmFtZXMgYW5kIHZhbHVlbmFtZXMuIAogKiBtdWx0aXBsZSB2YWx1ZXMgbWF5IGJlbG9uZyB0byBvbmUga2V5LCB0aGUgc3BlY2lhbCB2YWx1ZQogKiB3aXRoIG5hbWUgTlVMTCBpcyB0aGUgZGVmYXVsdCB2YWx1ZSB1c2VkIGJ5IHRoZSB3aW4zMQogKiBjb21wYXQgZnVuY3Rpb25zLgogKgogKiBDYWxscGF0aDoKICogUmVnUXVlcnlWYWx1ZTE2IC0+IFJlZ1F1ZXJ5VmFsdWUzMkEgLT4gUmVnUXVlcnlWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdRdWVyeVZhbHVlMzJXIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyVwogKi8KCi8qIFJlZ1F1ZXJ5VmFsdWVFeFcJCVtBRFZBUEkzMi4xNThdICovCkRXT1JEIFJlZ1F1ZXJ5VmFsdWVFeDMyVygKCUhLRVkJaGtleSwKCUxQV1NUUglscHN6VmFsdWVOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlRXgzMlcoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwKCQloa2V5LFcyQyhscHN6VmFsdWVOYW1lLDApLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoKCWxwa2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXAzMlcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJaWYgKGxwc3pWYWx1ZU5hbWU9PU5VTEwpIHsKCQkJaWYgKGxwYkRhdGEpIHsKCQkJCSooV0NIQVIqKWxwYkRhdGEgPSAwOwoJCQkJKmxwY2JEYXRhCT0gMjsKCQkJfQoJCQlpZiAobHBkd1R5cGUpCgkJCQkqbHBkd1R5cGUJPSBSRUdfU1o7CgkJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJCX0KCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOy8qRklYTUU6IGNvcnJlY3QgcmV0dXJuPyAqLwoJfQoJaWYgKGxwZHdUeXBlKQoJCSpscGR3VHlwZQk9IGxwa2V5LT52YWx1ZXNbaV0udHlwZTsKCWlmIChscGJEYXRhPT1OVUxMKSB7CgkJaWYgKGxwY2JEYXRhPT1OVUxMKQoJCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCQkqbHBjYkRhdGEJPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCWlmICgqbHBjYkRhdGE8bHBrZXktPnZhbHVlc1tpXS5sZW4pIHsKCQkqKFdDSEFSKilscGJEYXRhCgkJCT0gMDsKCQkqbHBjYkRhdGEJPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJfQoJbWVtY3B5KGxwYkRhdGEsbHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwa2V5LT52YWx1ZXNbaV0ubGVuKTsKCSpscGNiRGF0YQk9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ1F1ZXJ5VmFsdWVXCQlbQURWQVBJMzIuMTU5XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlMzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pTdWJLZXksCglMUFdTVFIJbHBzekRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJSEtFWQl4aGtleTsKCURXT1JECXJldCxscGR3VHlwZTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWUzMlcoJXgsJXMsJXAsJWxkKVxuLT4iLAoJCWhrZXksVzJDKGxwc3pTdWJLZXksMCksbHBzekRhdGEsCgkJbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CgoJLyogb25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0CT0gUmVnT3BlbktleTMyVyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXkJPSBoa2V5OwoKCWxwZHdUeXBlCT0gUkVHX1NaOwoJcmV0CT0gUmVnUXVlcnlWYWx1ZUV4MzJXKAoJCXhoa2V5LAoJCU5VTEwsCQkvKiB2YXJuYW1lIE5VTEwgLT4gY29tcGF0ICovCgkJTlVMTCwJCS8qIGxwZHdSZXNlcnZlZCwgbXVzdCBiZSBOVUxMICovCgkJJmxwZHdUeXBlLAoJCShMUEJZVEUpbHBzekRhdGEsCgkJbHBjYkRhdGEKCSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnUXVlcnlWYWx1ZUV4QQkJW0FEVkFQSTMyLjE1N10gKi8KRFdPUkQgUmVnUXVlcnlWYWx1ZUV4MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCUxQQllURQlidWY7CglEV09SRAlyZXQsbXl4bGVuOwoJRFdPUkQJKm15bGVuOwoJRFdPUkQJdHlwZTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWVFeDMyQSgleCwlcywlcCwlcCwlcCwlbGQpXG4tPiIsCgkJaGtleSxscHN6VmFsdWVOYW1lLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoJaWYgKGxwYkRhdGEpIHsKCQkvKiBkb3VibGUgYnVmZmVyICovCgkJYnVmCT0gKExQQllURSl4bWFsbG9jKCgqbHBjYkRhdGEpKjIpOwoJCW15eGxlbgk9ICpscGNiRGF0YSoyOwoJCW15bGVuCT0gJm15eGxlbjsKCX0gZWxzZSB7CgkJYnVmPU5VTEw7CgkJaWYgKGxwY2JEYXRhKSB7CgkJCW15eGxlbgk9ICpscGNiRGF0YSoyOwoJCQlteWxlbgk9ICZteXhsZW47CgkJfSBlbHNlCgkJCW15bGVuCT0gTlVMTDsKCX0KCWlmIChscHN6VmFsdWVOYW1lKQoJCWxwc3pWYWx1ZU5hbWVXPXN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UgCgkJbHBzelZhbHVlTmFtZVc9TlVMTDsKCglpZiAobHBkd1R5cGUpCgkJdHlwZT0qbHBkd1R5cGU7CglyZXQ9UmVnUXVlcnlWYWx1ZUV4MzJXKAoJCWhrZXksCgkJbHBzelZhbHVlTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCSZ0eXBlLAoJCWJ1ZiwKCQlteWxlbgoJKTsKCWlmIChscGR3VHlwZSkgCgkJKmxwZHdUeXBlPXR5cGU7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJaWYgKGJ1ZikgewoJCQlpZiAoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgewoJCQkJLyogY29udmVydCBVTklDT0RFIHRvIEFTQ0lJICovCgkJCQlzdHJjcHlXQShscGJEYXRhLChMUFdTVFIpYnVmKTsKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCQl9IGVsc2UgewoJCQkJaWYgKG15eGxlbj4qbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGJ1ZixteXhsZW4pOwoKCQkJCSpscGNiRGF0YQk9IG15eGxlbjsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCQl9Cgl9IGVsc2UgewoJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJfQoJaWYgKGJ1ZikKCQlmcmVlKGJ1Zik7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdRdWVyeVZhbHVlRXgJCVtLRVJORUwuMjI1XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlRXgxNigKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWVFeDE2KCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsCgkJaGtleSxscHN6VmFsdWVOYW1lLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoJcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQloa2V5LAoJCWxwc3pWYWx1ZU5hbWUsCgkJbHBkd1Jlc2VydmVkLAoJCWxwZHdUeXBlLAoJCWxwYkRhdGEsCgkJbHBjYkRhdGEKCSk7Cn0KCi8qIFJlZ1F1ZXJ5VmFsdWVBCQlbQURWQVBJMzIuMTU2XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelN1YktleSwKCUxQU1RSCWxwc3pEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlMzJBKCV4LCVzLCVwLCVsZClcbiIsCgkJaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoKCS8qIG9ubHkgb3BlbiBzdWJrZXksIGlmIHdlIHJlYWxseSBkbyBkZXNjZW5kICovCglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldAk9IFJlZ09wZW5LZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXkJPSBoa2V5OwoKCWxwZHdUeXBlCT0gUkVHX1NaOwoJcmV0CT0gUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCXhoa2V5LAoJCU5VTEwsCQkvKiBscHN6VmFsdWVOYW1lIE5VTEwgLT4gY29tcGF0ICovCgkJTlVMTCwJCS8qIGxwZHdSZXNlcnZlZCwgbXVzdCBiZSBOVUxMICovCgkJJmxwZHdUeXBlLAoJCShMUEJZVEUpbHBzekRhdGEsCgkJbHBjYkRhdGEKCSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnUXVlcnlWYWx1ZQkJW1NIRUxMLjZdIFtLRVJORUwuMjI0XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlMTYoCglIS0VZCWhrZXksCglMUFNUUglscHN6U3ViS2V5LAoJTFBTVFIJbHBzekRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlMTYoJXgsJXMsJXAsJWxkKVxuIiwKCQloa2V5LGxwc3pTdWJLZXksbHBzekRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CgkvKiBIQUNLOiB0aGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcwoJICogICAgICAgYW55d2F5LCBzbyB3ZSBqdXN0IG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4KCSAqICAgICAgICh0aGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5OykgaG9wZWZ1bGx5IGZpeGVzIEFsZHVzIEZINCkKCSAqLwoJaWYgKGxwY2JEYXRhKQoJCSpscGNiRGF0YSAmPSAweEZGRkY7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZTMyQShoa2V5LGxwc3pTdWJLZXksbHBzekRhdGEsbHBjYkRhdGEpOwp9CgovKgogKiBTZXR0aW5nIHZhbHVlcyBvZiBSZWdpc3RyeSBrZXlzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdTZXRWYWx1ZTE2IC0+IFJlZ1NldFZhbHVlMzJBIC0+IFJlZ1NldFZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlMzJXICAgLT4gUmVnU2V0VmFsdWVFeDMyVwogKi8KCi8qIFJlZ1NldFZhbHVlRXhXCQlbQURWQVBJMzIuMTcwXSAqLwpEV09SRCBSZWdTZXRWYWx1ZUV4MzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pWYWx1ZU5hbWUsCglEV09SRAlkd1Jlc2VydmVkLAoJRFdPUkQJZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglEV09SRAljYkRhdGEKKSB7CglMUEtFWVNUUlVDVAlscGtleTsKCWludAkJaTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlRXgzMlcoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLAoJCWhrZXksVzJDKGxwc3pWYWx1ZU5hbWUsMCksZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEKCSk7CgkvKiB3ZSBubyBsb25nZXIgY2FyZSBhYm91dCB0aGUgbHBiRGF0YSB0eXBlIGhlcmUuLi4gKi8KCWxwa2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgoJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXAzMlcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkJKGxwa2V5LT5ucm9mdmFsdWVzKzEpKnNpemVvZihLRVlWQUxVRSkKCQkJCSk7CgkJbHBrZXktPm5yb2Z2YWx1ZXMrKzsKCQltZW1zZXQobHBrZXktPnZhbHVlcytpLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7Cgl9CglpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCWlmIChscHN6VmFsdWVOYW1lKQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBzdHJkdXBXKGxwc3pWYWx1ZU5hbWUpOwoJCWVsc2UKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gTlVMTDsKCWxwa2V5LT52YWx1ZXNbaV0ubGVuCT0gY2JEYXRhOwoJbHBrZXktPnZhbHVlc1tpXS50eXBlCT0gZHdUeXBlOwoJaWYgKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSAhPU5VTEwpCgkJZnJlZShscGtleS0+dmFsdWVzW2ldLmRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5kYXRhCT0gKExQQllURSl4bWFsbG9jKGNiRGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmxhc3Rtb2RpZmllZCA9IHRpbWUoTlVMTCk7CgltZW1jcHkobHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwYkRhdGEsY2JEYXRhKTsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdTZXRWYWx1ZUV4QQkJW0FEVkFQSTMyLjE2OV0gKi8KRFdPUkQgUmVnU2V0VmFsdWVFeDMyQSgKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglEV09SRAlkd1Jlc2VydmVkLAoJRFdPUkQJZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglEV09SRAljYkRhdGEKKSB7CglMUEJZVEUJYnVmOwoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVFeDMyQSgleCwlcywlbGQsJWxkLCVwLCVsZClcbi0+IiwKCQloa2V5LGxwc3pWYWx1ZU5hbWUsZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEKCSk7CglpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCWJ1Zj0oTFBCWVRFKXN0cmR1cEEyVyhscGJEYXRhKTsKCQljYkRhdGE9MipzdHJsZW4obHBiRGF0YSkrMjsKCX0gZWxzZQoJCWJ1Zj1scGJEYXRhOwoJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJbHBzelZhbHVlTmFtZVcgPSBzdHJkdXBBMlcobHBzelZhbHVlTmFtZSk7CgllbHNlCgkJbHBzelZhbHVlTmFtZVcgPSBOVUxMOwoJcmV0PVJlZ1NldFZhbHVlRXgzMlcoaGtleSxscHN6VmFsdWVOYW1lVyxkd1Jlc2VydmVkLGR3VHlwZSxidWYsY2JEYXRhKTsKCWlmIChscHN6VmFsdWVOYW1lVykKCQlmcmVlKGxwc3pWYWx1ZU5hbWVXKTsKCWlmIChidWYhPWxwYkRhdGEpCgkJZnJlZShidWYpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnU2V0VmFsdWVFeAkJW0tFUk5FTC4yMjZdICovCkRXT1JEIFJlZ1NldFZhbHVlRXgxNigKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglEV09SRAlkd1Jlc2VydmVkLAoJRFdPUkQJZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglEV09SRAljYkRhdGEKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlRXgxNigleCwlcywlbGQsJWxkLCVwLCVsZClcbi0+IiwKCQloa2V5LGxwc3pWYWx1ZU5hbWUsZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEKCSk7CglyZXR1cm4gUmVnU2V0VmFsdWVFeDMyQShoa2V5LGxwc3pWYWx1ZU5hbWUsZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEpOwp9CgovKiBSZWdTZXRWYWx1ZVcJCQlbQURWQVBJMzIuMTcxXSAqLwpEV09SRCBSZWdTZXRWYWx1ZTMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCURXT1JECWR3VHlwZSwKCUxQQ1dTVFIJbHBzekRhdGEsCglEV09SRAljYkRhdGEKKSB7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWUzMlcoJXgsJXMsJWxkLCVzLCVsZClcbi0+IiwKCQloa2V5LFcyQyhscHN6U3ViS2V5LDApLGR3VHlwZSxXMkMobHBzekRhdGEsMCksY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MzJXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJZnByaW50ZihzdGRkZWIsIlJlZ1NldFZhbHVlWCBjYWxsZWQgd2l0aCBkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzIpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlWCBjYWxsZWQgd2l0aCBsZW49JWxkICE9IHN0cmxlbiglcykrMT0lZCFcbiIsCgkJCWNiRGF0YSxXMkMobHBzekRhdGEsMCksMipsc3RybGVuMzJXKGxwc3pEYXRhKSsyCgkJKTsKCQljYkRhdGE9Mipsc3RybGVuMzJXKGxwc3pEYXRhKSsyOwoJfQoJcmV0PVJlZ1NldFZhbHVlRXgzMlcoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoaGtleSE9eGhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKCn0KLyogUmVnU2V0VmFsdWVBCQkJW0FEVkFQSTMyLjE2OF0gKi8KRFdPUkQgUmVnU2V0VmFsdWUzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCURXT1JECWR3VHlwZSwKCUxQQ1NUUglscHN6RGF0YSwKCURXT1JECWNiRGF0YQopIHsKCURXT1JECXJldDsKCUhLRVkJeGhrZXk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZTMyQSgleCwlcywlbGQsJXMsJWxkKVxuLT4iLAoJCWhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MTYoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CgoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZUEgY2FsbGVkIHdpdGggZHdUeXBlPSVsZCFcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9c3RybGVuKGxwc3pEYXRhKSsxKQoJCWNiRGF0YT1zdHJsZW4obHBzekRhdGEpKzE7CglyZXQ9UmVnU2V0VmFsdWVFeDMyQSh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdTZXRWYWx1ZQkJCVtLRVJORUwuMjIxXSBbU0hFTEwuNV0gKi8KRFdPUkQgUmVnU2V0VmFsdWUxNigKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdUeXBlLAoJTFBDU1RSCWxwc3pEYXRhLAoJRFdPUkQJY2JEYXRhCikgewoJRFdPUkQJcmV0OwoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZTE2KCV4LCVzLCVsZCwlcywlbGQpXG4tPiIsCgkJaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEKCSk7CglyZXQ9UmVnU2V0VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwoJcmV0dXJuIHJldDsKfQoKLyogCiAqIEtleSBFbnVtZXJhdGlvbgogKgogKiBDYWxscGF0aDoKICogUmVnRW51bUtleTE2IC0+IFJlZ0VudW1LZXkzMkEgLT4gUmVnRW51bUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdFbnVtS2V5MzJXICAgLT4gUmVnRW51bUtleUV4MzJXCiAqLwoKLyogUmVnRW51bUtleUV4VwkJW0FEVkFQSTMyLjEzOV0gKi8KRFdPUkQgUmVnRW51bUtleUV4MzJXKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQV1NUUglscHN6TmFtZSwKCUxQRFdPUkQJbHBjY2hOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUFdTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJRklMRVRJTUUJKmZ0CikgewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bUtleUV4MzJXKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSwqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdAoJKTsKCWxwa2V5PWxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKCFscGtleS0+bmV4dHN1YikKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWxweGtleT1scGtleS0+bmV4dHN1YjsKCXdoaWxlIChpU3Via2V5ICYmIGxweGtleSkgewoJCWlTdWJrZXktLTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJaWYgKGlTdWJrZXkgfHwgIWxweGtleSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWlmICgyKmxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKSsyPipscGNjaE5hbWUpCgkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCW1lbWNweShscHN6TmFtZSxscHhrZXktPmtleW5hbWUsbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKjIrMik7CglpZiAobHBzekNsYXNzKSB7CgkJLyogd2hhdCBzaG91bGQgd2Ugd3JpdGUgaW50byBpdD8gKi8KCQkqbHBzekNsYXNzCQk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgp9CgovKiBSZWdFbnVtS2V5VwkJCVtBRFZBUEkzMi4xNDBdICovCkRXT1JEIFJlZ0VudW1LZXkzMlcoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBXU1RSCWxwc3pOYW1lLAoJRFdPUkQJbHBjY2hOYW1lCikgewoJRklMRVRJTUUJZnQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5MzJXKCV4LCVsZCwlcCwlbGQpXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZQoJKTsKCXJldHVybiBSZWdFbnVtS2V5RXgzMlcoaGtleSxpU3Via2V5LGxwc3pOYW1lLCZscGNjaE5hbWUsTlVMTCxOVUxMLE5VTEwsJmZ0KTsKfQovKiBSZWdFbnVtS2V5RXhBCQlbQURWQVBJMzIuMTM4XSAqLwpEV09SRCBSZWdFbnVtS2V5RXgzMkEoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBTVFIJbHBzek5hbWUsCglMUERXT1JECWxwY2NoTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJRklMRVRJTUUJKmZ0CikgewoJRFdPUkQJcmV0LGxwY2NoTmFtZVcsbHBjY2hDbGFzc1c7CglMUFdTVFIJbHBzek5hbWVXLGxwc3pDbGFzc1c7CgoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bUtleUV4MzJBKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLCpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0CgkpOwoJaWYgKGxwc3pOYW1lKSB7CgkJbHBzek5hbWVXCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaE5hbWUqMik7CgkJbHBjY2hOYW1lVwk9ICpscGNjaE5hbWUqMjsKCX0gZWxzZSB7CgkJbHBzek5hbWVXCT0gTlVMTDsKCQlscGNjaE5hbWVXIAk9IDA7Cgl9CglpZiAobHBzekNsYXNzKSB7CgkJbHBzekNsYXNzVwkJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MqMik7CgkJbHBjY2hDbGFzc1cJPSAqbHBjY2hDbGFzcyoyOwoJfSBlbHNlIHsKCQlscHN6Q2xhc3NXCT0wOwoJCWxwY2NoQ2xhc3NXPTA7Cgl9CglyZXQ9UmVnRW51bUtleUV4MzJXKAoJCWhrZXksCgkJaVN1YmtleSwKCQlscHN6TmFtZVcsCgkJJmxwY2NoTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJJmxwY2NoQ2xhc3NXLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCXN0cmNweVdBKGxwc3pOYW1lLGxwc3pOYW1lVyk7CgkJKmxwY2NoTmFtZT1zdHJsZW4obHBzek5hbWUpOwoJCWlmIChscHN6Q2xhc3NXKSB7CgkJCXN0cmNweVdBKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCQkJKmxwY2NoQ2xhc3M9c3RybGVuKGxwc3pDbGFzcyk7CgkJfQoJfQoJaWYgKGxwc3pOYW1lVykKCQlmcmVlKGxwc3pOYW1lVyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnRW51bUtleUEJCQlbQURWQVBJMzIuMTM3XSAqLwpEV09SRCBSZWdFbnVtS2V5MzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQU1RSCWxwc3pOYW1lLAoJRFdPUkQJbHBjY2hOYW1lCikgewoJRklMRVRJTUUJZnQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5MzJBKCV4LCVsZCwlcCwlbGQpXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZQoJKTsKCXJldHVybglSZWdFbnVtS2V5RXgzMkEoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lLAoJCSZscGNjaE5hbWUsCgkJTlVMTCwKCQlOVUxMLAoJCU5VTEwsCgkJJmZ0CgkpOwp9CgovKiBSZWdFbnVtS2V5CQkJW1NIRUxMLjddIFtLRVJORUwuMjE2XSAqLwpEV09SRCBSZWdFbnVtS2V5MTYoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBTVFIJbHBzek5hbWUsCglEV09SRAlscGNjaE5hbWUKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0VudW1LZXkxNigleCwlbGQsJXAsJWxkKVxuLT4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUKCSk7CglyZXR1cm4gUmVnRW51bUtleTMyQShoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKfQoKLyogCiAqIEVudW1lcmF0ZSBSZWdpc3RyeSBWYWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1WYWx1ZTE2IC0+IFJlZ0VudW1WYWx1ZTMyQSAtPiBSZWdFbnVtVmFsdWUzMlcKICovCgovKiBSZWdFbnVtVmFsdWVXCQlbQURWQVBJMzIuMTQyXSAqLwpEV09SRCBSZWdFbnVtVmFsdWUzMlcoCglIS0VZCWhrZXksCglEV09SRAlpVmFsdWUsCglMUFdTVFIJbHBzelZhbHVlLAoJTFBEV09SRAlscGNjaFZhbHVlLAoJTFBEV09SRAlscGRSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bVZhbHVlMzJXKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YQoJKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBrZXktPm5yb2Z2YWx1ZXM8PWlWYWx1ZSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCXZhbAk9IGxwa2V5LT52YWx1ZXMraVZhbHVlOwoKCWlmICh2YWwtPm5hbWUpIHsKCQlpZiAobHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMj4qbHBjY2hWYWx1ZSkgewoJCQkqbHBjY2hWYWx1ZSA9IGxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscHN6VmFsdWUsdmFsLT5uYW1lLDIqbHN0cmxlbjMyVyh2YWwtPm5hbWUpKzIpOwoJCSpscGNjaFZhbHVlPWxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7Cgl9IGVsc2UgewoJCS8qIGhvdyB0byBoYW5kbGUgTlVMTCB2YWx1ZT8gKi8KCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDI7Cgl9CgkqbHBkd1R5cGU9dmFsLT50eXBlOwoJaWYgKGxwYkRhdGEpIHsKCQlpZiAodmFsLT5sZW4+KmxwY2JEYXRhKQoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCW1lbWNweShscGJEYXRhLHZhbC0+ZGF0YSx2YWwtPmxlbik7CgkJKmxwY2JEYXRhID0gdmFsLT5sZW47Cgl9CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnRW51bVZhbHVlQQkJW0FEVkFQSTMyLjE0MV0gKi8KRFdPUkQgUmVnRW51bVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVZhbHVlLAoJTFBTVFIJbHBzelZhbHVlLAoJTFBEV09SRAlscGNjaFZhbHVlLAoJTFBEV09SRAlscGRSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUFdTVFIJbHBzelZhbHVlVzsKCUxQQllURQlscGJEYXRhVzsKCURXT1JECXJldCxscGNiRGF0YVc7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtVmFsdWUzMkEoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhCgkpOwoKCWxwc3pWYWx1ZVcgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoVmFsdWUqMik7CglpZiAobHBiRGF0YSkgewoJCWxwYkRhdGFXID0gKExQQllURSl4bWFsbG9jKCpscGNiRGF0YSoyKTsKCQlscGNiRGF0YVcgPSAqbHBjYkRhdGEqMjsKCX0gZWxzZQoJCWxwYkRhdGFXID0gTlVMTDsKCXJldD1SZWdFbnVtVmFsdWUzMlcoCgkJaGtleSwKCQlpVmFsdWUsCgkJbHBzelZhbHVlVywKCQlscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLAoJCWxwZHdUeXBlLAoJCWxwYkRhdGFXLAoJCSZscGNiRGF0YVcKCSk7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCXN0cmNweVdBKGxwc3pWYWx1ZSxscHN6VmFsdWVXKTsKCQlpZiAobHBiRGF0YSkgewoJCQlpZiAoKDE8PCpscGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJc3RyY3B5V0EobHBiRGF0YSwoTFBXU1RSKWxwYkRhdGFXKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChscGNiRGF0YVcgPiAqbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGxwYkRhdGFXLGxwY2JEYXRhVyk7CgkJCX0KCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCX0KCX0KCWlmIChscGJEYXRhVykKCQlmcmVlKGxwYkRhdGFXKTsKCWlmIChscHN6VmFsdWVXKQoJCWZyZWUobHBzelZhbHVlVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdFbnVtVmFsdWUJCQlbS0VSTkVMLjIyM10gKi8KRFdPUkQgUmVnRW51bVZhbHVlMTYoCglIS0VZCWhrZXksCglEV09SRAlpVmFsdWUsCglMUFNUUglscHN6VmFsdWUsCglMUERXT1JECWxwY2NoVmFsdWUsCglMUERXT1JECWxwZFJlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bVZhbHVlKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YQoJKTsKCXJldHVybiBSZWdFbnVtVmFsdWUzMkEoCgkJaGtleSwKCQlpVmFsdWUsCgkJbHBzelZhbHVlLAoJCWxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YSwKCQlscGNiRGF0YQoJKTsKfQoKLyogCiAqICBDbG9zZSByZWdpc3RyeSBrZXkKICovCi8qIFJlZ0Nsb3NlS2V5CQkJW1NIRUxMLjNdIFtLRVJORUwuMjIwXSBbQURWQVBJMzIuMTI2XSAqLwpEV09SRCBSZWdDbG9zZUtleShIS0VZIGhrZXkpIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ2xvc2VLZXkoJXgpXG4iLGhrZXkpOwoJcmVtb3ZlX2hhbmRsZShoa2V5KTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9Ci8qIAogKiBEZWxldGUgcmVnaXN0cnkga2V5CiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVLZXkxNiAtPiBSZWdEZWxldGVLZXkzMkEgLT4gUmVnRGVsZXRlS2V5MzJXCiAqLwovKiBSZWdEZWxldGVLZXlXCQlbQURWQVBJMzIuMTM0XSAqLwpEV09SRCBSZWdEZWxldGVLZXkzMlcoSEtFWSBoa2V5LExQV1NUUiBscHN6U3ViS2V5KSB7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdEZWxldGVLZXkzMlcoJXgsJXMpXG4iLAoJCWhrZXksVzJDKGxwc3pTdWJLZXksMCkKCSk7CglscE5leHRLZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBOZXh0S2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgkvKiB3ZSBuZWVkIHRvIGtub3cgdGhlIHByZXZpb3VzIGtleSBpbiB0aGUgaGllci4gKi8KCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKGk8d3BjLTEpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCS8qIG5vdCBmb3VuZCBpcyBzdWNjZXNzICovCgkJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJbHB4a2V5CT0gbHBOZXh0S2V5LT5uZXh0c3ViOwoJbHBscFByZXZLZXkgPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKCFsc3RyY21wMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJCT0gbHB4a2V5LT5uZXh0OwoJfQoJaWYgKCFscHhrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7CglpZiAobHB4a2V5LT5uZXh0c3ViKQoJCXJldHVybiBTSEVMTF9FUlJPUl9DQU5UV1JJVEU7CgkqbHBscFByZXZLZXkJPSBscHhrZXktPm5leHQ7CglmcmVlKGxweGtleS0+a2V5bmFtZSk7CglpZiAobHB4a2V5LT5jbGFzcykKCQlmcmVlKGxweGtleS0+Y2xhc3MpOwoJaWYgKGxweGtleS0+dmFsdWVzKQoJCWZyZWUobHB4a2V5LT52YWx1ZXMpOwoJZnJlZShscHhrZXkpOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybglTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdEZWxldGVLZXlBCQlbQURWQVBJMzIuMTMzXSAqLwpEV09SRCBSZWdEZWxldGVLZXkzMkEoSEtFWSBoa2V5LExQQ1NUUiBscHN6U3ViS2V5KSB7CglMUFdTVFIJbHBzelN1YktleVc7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdEZWxldGVLZXkzMkEoJXgsJXMpXG4iLAoJCWhrZXksbHBzelN1YktleQoJKTsKCWxwc3pTdWJLZXlXPXN0cmR1cEEyVyhscHN6U3ViS2V5KTsKCXJldD1SZWdEZWxldGVLZXkzMlcoaGtleSxscHN6U3ViS2V5Vyk7CglmcmVlKGxwc3pTdWJLZXlXKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ0RlbGV0ZUtleQkJCVtTSEVMTC40XSBbS0VSTkVMLjIxOV0gKi8KRFdPUkQgUmVnRGVsZXRlS2V5MTYoSEtFWSBoa2V5LExQQ1NUUiBscHN6U3ViS2V5KSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0RlbGV0ZUtleTE2KCV4LCVzKVxuIiwKCQloa2V5LGxwc3pTdWJLZXkKCSk7CglyZXR1cm4gUmVnRGVsZXRlS2V5MzJBKGhrZXksbHBzelN1YktleSk7Cn0KCi8qIAogKiBEZWxldGUgcmVnaXN0cnkgdmFsdWUKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZVZhbHVlMTYgLT4gUmVnRGVsZXRlVmFsdWUzMkEgLT4gUmVnRGVsZXRlVmFsdWUzMlcKICovCi8qIFJlZ0RlbGV0ZVZhbHVlVwkJW0FEVkFQSTMyLjEzNl0gKi8KRFdPUkQgUmVnRGVsZXRlVmFsdWUzMlcoSEtFWSBoa2V5LExQV1NUUiBscHN6VmFsdWUpIHsKCURXT1JECQlpOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0RlbGV0ZVZhbHVlMzJXKCV4LCVzKVxuIiwKCQloa2V5LFcyQyhscHN6VmFsdWUsMCkKCSk7CglscGtleT1sb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmIChscHN6VmFsdWUpIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21wMzJXKGxwa2V5LT52YWx1ZXNbaV0ubmFtZSxscHN6VmFsdWUpCgkJCSkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7LypGSVhNRTogY29ycmVjdCBlcnJvcmNvZGU/ICovCgl2YWwJPSBscGtleS0+dmFsdWVzK2k7CglpZiAodmFsLT5uYW1lKSBmcmVlKHZhbC0+bmFtZSk7CglpZiAodmFsLT5kYXRhKSBmcmVlKHZhbC0+ZGF0YSk7CgltZW1jcHkoCQoJCWxwa2V5LT52YWx1ZXMraSwKCQlscGtleS0+dmFsdWVzK2krMSwKCQlzaXplb2YoS0VZVkFMVUUpKihscGtleS0+bnJvZnZhbHVlcy1pLTEpCgkpOwoJbHBrZXktPnZhbHVlcwk9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJbHBrZXktPnZhbHVlcywKCQkJCShscGtleS0+bnJvZnZhbHVlcy0xKSpzaXplb2YoS0VZVkFMVUUpCgkJCSk7CglscGtleS0+bnJvZnZhbHVlcy0tOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0RlbGV0ZVZhbHVlQQkJW0FEVkFQSTMyLjEzNV0gKi8KRFdPUkQgUmVnRGVsZXRlVmFsdWUzMkEoSEtFWSBoa2V5LExQU1RSIGxwc3pWYWx1ZSkgewoJTFBXU1RSCWxwc3pWYWx1ZVc7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoIHN0ZGRlYiwgIlJlZ0RlbGV0ZVZhbHVlMzJBKCV4LCVzKVxuIiwgaGtleSxscHN6VmFsdWUgKTsKCWlmIChscHN6VmFsdWUpCgkJbHBzelZhbHVlVz1zdHJkdXBBMlcobHBzelZhbHVlKTsKCWVsc2UKCQlscHN6VmFsdWVXPU5VTEw7CglyZXQ9UmVnRGVsZXRlVmFsdWUzMlcoaGtleSxscHN6VmFsdWVXKTsKCWlmIChscHN6VmFsdWVXKQoJCWZyZWUobHBzelZhbHVlVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdEZWxldGVWYWx1ZQkJW0tFUk5FTC4yMjJdICovCkRXT1JEIFJlZ0RlbGV0ZVZhbHVlMTYoSEtFWSBoa2V5LExQU1RSIGxwc3pWYWx1ZSkgewoJZHByaW50Zl9yZWcoIHN0ZGRlYiwiUmVnRGVsZXRlVmFsdWUxNigleCwlcylcbiIsIGhrZXksbHBzelZhbHVlICk7CglyZXR1cm4gUmVnRGVsZXRlVmFsdWUzMkEoaGtleSxscHN6VmFsdWUpOwp9CgovKiBSZWdGbHVzaEtleQkJCVtBRFZBUEkzMi4xNDNdIFtLRVJORUwuMjI3XSAqLwpEV09SRCBSZWdGbHVzaEtleShIS0VZIGhrZXkpIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRmx1c2hLZXkoJXgpLCBTVFVCLlxuIixoa2V5KTsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBGSVhNRTogbHBjY2hYWFhYIC4uLiBpcyB0aGlzIGNvdW50aW5nIGluIFdDSEFSUyBvciBpbiBCWVRFcyA/PyAqLwoKLyogUmVnUXVlcnlJbmZvS2V5VwkJW0FEVkFQSTMyLjE1M10gKi8KRFdPUkQgUmVnUXVlcnlJbmZvS2V5MzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pDbGFzcywKCUxQRFdPUkQJbHBjY2hDbGFzcywKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGNTdWJLZXlzLAoJTFBEV09SRAlscGNjaE1heFN1YmtleSwKCUxQRFdPUkQJbHBjY2hNYXhDbGFzcywKCUxQRFdPUkQJbHBjVmFsdWVzLAoJTFBEV09SRAlscGNjaE1heFZhbHVlTmFtZSwKCUxQRFdPUkQJbHBjY2JNYXhWYWx1ZURhdGEsCglMUERXT1JECWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCglGSUxFVElNRQkqZnQKKSB7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CglpbnQJCW5yb2ZrZXlzLG1heHN1YmtleSxtYXhjbGFzcyxtYXh2YWx1ZXMsbWF4dm5hbWUsbWF4dmRhdGE7CglpbnQJCWk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeUluZm9LZXkzMlcoJXgsLi4uLi4uKVxuIixoa2V5KTsKCWxwa2V5PWxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKGxwc3pDbGFzcykgewoJCWlmIChscGtleS0+Y2xhc3MpIHsKCQkJaWYgKGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyKzI+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQkJfQoJCQkqbHBjY2hDbGFzcz1sc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCQkJbWVtY3B5KGxwc3pDbGFzcyxscGtleS0+Y2xhc3MsbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKTsKCQl9IGVsc2UgewoJCQkqbHBzekNsYXNzCT0gMDsKCQkJKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7Cgl9CglscHhrZXk9bHBrZXktPm5leHRzdWI7Cglucm9ma2V5cz1tYXhzdWJrZXk9bWF4Y2xhc3M9bWF4dmFsdWVzPW1heHZuYW1lPW1heHZkYXRhPTA7Cgl3aGlsZSAobHB4a2V5KSB7CgkJbnJvZmtleXMrKzsKCQlpZiAobHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpPm1heHN1YmtleSkKCQkJbWF4c3Via2V5PWxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKTsKCQlpZiAobHB4a2V5LT5jbGFzcyAmJiBsc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpPm1heGNsYXNzKQoJCQltYXhjbGFzcz1sc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpOwoJCWlmIChscHhrZXktPm5yb2Z2YWx1ZXM+bWF4dmFsdWVzKQoJCQltYXh2YWx1ZXM9bHB4a2V5LT5ucm9mdmFsdWVzOwoJCWZvciAoaT0wO2k8bHB4a2V5LT5ucm9mdmFsdWVzO2krKykgewoJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJaWYgKHZhbC0+bmFtZSAmJiBsc3RybGVuMzJXKHZhbC0+bmFtZSk+bWF4dm5hbWUpCgkJCQltYXh2bmFtZT1sc3RybGVuMzJXKHZhbC0+bmFtZSk7CgkJCWlmICh2YWwtPmxlbj5tYXh2ZGF0YSkKCQkJCW1heHZkYXRhPXZhbC0+bGVuOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJaWYgKCFtYXhjbGFzcykgbWF4Y2xhc3MJPSAxOwoJaWYgKCFtYXh2bmFtZSkgbWF4dm5hbWUJPSAxOwoJaWYgKGxwY1N1YktleXMpCgkJKmxwY1N1YktleXMJPSBucm9ma2V5czsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkJPSBtYXhzdWJrZXkqMjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzCT0gbWF4Y2xhc3MqMjsKCWlmIChscGNWYWx1ZXMpCgkJKmxwY1ZhbHVlcwk9IG1heHZhbHVlczsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWU9IG1heHZuYW1lOwoJaWYgKGxwY2NiTWF4VmFsdWVEYXRhKQoJCSpscGNjYk1heFZhbHVlRGF0YT0gbWF4dmRhdGE7CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnUXVlcnlJbmZvS2V5QQkJW0FEVkFQSTMyLjE1Ml0gKi8KRFdPUkQgUmVnUXVlcnlJbmZvS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwY1N1YktleXMsCglMUERXT1JECWxwY2NoTWF4U3Via2V5LAoJTFBEV09SRAlscGNjaE1heENsYXNzLAoJTFBEV09SRAlscGNWYWx1ZXMsCglMUERXT1JECWxwY2NoTWF4VmFsdWVOYW1lLAoJTFBEV09SRAlscGNjYk1heFZhbHVlRGF0YSwKCUxQRFdPUkQJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCUZJTEVUSU1FCSpmdAopIHsKCUxQV1NUUgkJbHBzekNsYXNzVzsKCURXT1JECQlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeUluZm9LZXkzMkEoJXgsLi4uLi4uKVxuIixoa2V5KTsKCWlmIChscHN6Q2xhc3MpIHsKCQkqbHBjY2hDbGFzcyo9IDI7CgkJbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MpOwoKCX0gZWxzZQoJCWxwc3pDbGFzc1cgID0gTlVMTDsKCXJldD1SZWdRdWVyeUluZm9LZXkzMlcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpCgkJc3RyY3B5V0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJaWYgKGxwY2NoQ2xhc3MpCgkJKmxwY2NoQ2xhc3MvPTI7CglpZiAobHBjY2hNYXhTdWJrZXkpCgkJKmxwY2NoTWF4U3Via2V5Lz0yOwoJaWYgKGxwY2NoTWF4Q2xhc3MpCgkJKmxwY2NoTWF4Q2xhc3MvPTI7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lLz0yOwoJaWYgKGxwc3pDbGFzc1cpCgkJZnJlZShscHN6Q2xhc3NXKTsKCXJldHVybiByZXQ7Cn0K