LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxwd2QuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgInN0cmluZzMyLmgiCQojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCi8qIEZJWE1FOiBmb2xsb3dpbmcgZGVmaW5lcyBzaG91bGQgYmUgY29uZmlndXJlZCBnbG9iYWwgLi4uICovCgovKiBOT1RFOiBkbyBub3QgYXBwZW5kIGEgLy4gbGludXgnIG1rZGlyKCkgV0lMTCBGQUlMIGlmIHlvdSBkbyB0aGF0ICovCiNkZWZpbmUgV0lORV9QUkVGSVgJCQkiLy53aW5lIgojZGVmaW5lIFNBVkVfVVNFUlNfREVGQVVMVAkJIi91c3IvbG9jYWwvZXRjL3dpbmUudXNlcnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVAkiL3Vzci9sb2NhbC9ldGMvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfQ1VSUkVOVF9VU0VSCQkidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FCQkic3lzdGVtLnJlZyIKCiNkZWZpbmUgS0VZX1JFR0lTVFJZCSJTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnkiCiNkZWZpbmUgVkFMX1NBVkVVUERBVEVECSJTYXZlT25seVVwZGF0ZWRLZXlzIgoKLyogb25lIHZhbHVlIG9mIGEga2V5ICovCnR5cGVkZWYgc3RydWN0IHRhZ0tFWVZBTFVFCnsKICAgIExQV1NUUiAgIG5hbWU7ICAgICAgICAgIC8qIG5hbWUgb2YgdmFsdWUgKFVOSUNPREUpIG9yIE5VTEwgZm9yIHdpbjMxICovCiAgICBEV09SRCAgICB0eXBlOyAgICAgICAgICAvKiB0eXBlIG9mIHZhbHVlICovCiAgICBEV09SRCAgICBsZW47ICAgICAgICAgICAvKiBsZW5ndGggb2YgZGF0YSAqLwogICAgRFdPUkQgICAgbGFzdG1vZGlmaWVkOyAgLyogdGltZSBvZiBzZWNvbmRzIHNpbmNlIDEuMS4xOTcwICovCiAgICBMUEJZVEUgICBkYXRhOyAgICAgICAgICAvKiBjb250ZW50LCBtYXkgYmUgc3RyaW5ncywgYmluYXJpZXMsIGV0Yy4gKi8KfSBLRVlWQUxVRSwqTFBLRVlWQUxVRTsKCi8qIGEgcmVnaXN0cnkga2V5ICovCnR5cGVkZWYgc3RydWN0IHRhZ0tFWVNUUlVDVAp7CiAgICBMUFdTVFIgICAgICAgICAgICAgICBrZXluYW1lOyAgICAgICAvKiBuYW1lIG9mIFRISVMga2V5IChVTklDT0RFKSAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgZmxhZ3M7ICAgICAgICAgLyogZmxhZ3MuICovCiAgICBMUFdTVFIgICAgICAgICAgICAgICBjbGFzczsKICAgIC8qIHZhbHVlcyAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgbnJvZnZhbHVlczsgICAgLyogbnIgb2YgdmFsdWVzIGluIFRISVMga2V5ICovCiAgICBMUEtFWVZBTFVFICAgICAgICAgICB2YWx1ZXM7ICAgICAgICAvKiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIC8qIGtleSBtYW5hZ2VtZW50IHBvaW50ZXJzICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0OyAgICAgICAgICAvKiBuZXh0IGtleSBvbiBzYW1lIGhpZXJhcmNoeSAqLwogICAgc3RydWN0IHRhZ0tFWVNUUlVDVAkqbmV4dHN1YjsgICAgICAgLyoga2V5cyB0aGF0IGhhbmcgYmVsb3cgVEhJUyBrZXkgKi8KfSBLRVlTVFJVQ1QsICpMUEtFWVNUUlVDVDsKCgpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY2xhc3Nlc19yb290PU5VTEw7CS8qIHdpbmRvd3MgMy4xIGdsb2JhbCB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X2N1cnJlbnRfdXNlcj1OVUxMOwkvKiB1c2VyIHNwZWNpZmljIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfbG9jYWxfbWFjaGluZT1OVUxMOy8qIG1hY2hpbmUgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV91c2Vycz1OVUxMOwkvKiBhbGwgdXNlcnM/ICovCgovKiBkeW5hbWljLCBub3Qgc2F2ZWQgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3BlcmZvcm1hbmNlX2RhdGE9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2N1cnJlbnRfY29uZmlnPU5VTEw7CnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9keW5fZGF0YT1OVUxMOwoKLyogd2hhdCB2YWx1ZXR5cGVzIGRvIHdlIG5lZWQgdG8gY29udmVydD8gKi8KI2RlZmluZSBVTklDT05WTUFTSwkoKDE8PFJFR19TWil8KDE8PFJFR19NVUxUSV9TWil8KDE8PFJFR19FWFBBTkRfU1opKQoKI2RlZmluZSBzdHJkdXBBMlcoeCkJU1RSSU5HMzJfRHVwQW5zaVRvVW5pKHgpCiNkZWZpbmUgc3RyZHVwVyh4KQlTVFJJTkczMl9zdHJkdXBXKHgpCiNkZWZpbmUgc3RyY2hyVyhhLGMpCVNUUklORzMyX2xzdHJjaHJXKGEsYykKCnN0YXRpYyBzdHJ1Y3Qgb3BlbmhhbmRsZSB7CglMUEtFWVNUUlVDVAlscGtleTsKCUhLRVkJCWhrZXk7CglSRUdTQU0JCWFjY2Vzc21hc2s7Cn0gICpvcGVuaGFuZGxlcz1OVUxMOwpzdGF0aWMgaW50CW5yb2ZvcGVuaGFuZGxlcz0wOwpzdGF0aWMgaW50CWN1cnJlbnRoYW5kbGU9MTsKCnN0YXRpYyB2b2lkCmFkZF9oYW5kbGUoSEtFWSBoa2V5LExQS0VZU1RSVUNUIGxwa2V5LFJFR1NBTSBhY2Nlc3NtYXNrKSB7CglpbnQJaTsKCglmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspIHsKCQlpZiAob3BlbmhhbmRsZXNbaV0ubHBrZXk9PWxwa2V5KSB7CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiYWRkX2hhbmRsZTpUcmllZCB0byBhZGQgJXAgdHdpY2UhXG4iLGxwa2V5KTsKCQl9CgkJaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKCQkJZHByaW50Zl9yZWcoc3RkZGViLCJhZGRfaGFuZGxlOlRyaWVkIHRvIGFkZCAlbHggdHdpY2UhXG4iLChMT05HKWhrZXkpOwoJCX0KCX0KCW9wZW5oYW5kbGVzPXhyZWFsbG9jKAlvcGVuaGFuZGxlcywKCQkJCXNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKQoJCSk7CglvcGVuaGFuZGxlc1tpXS5scGtleQk9IGxwa2V5OwoJb3BlbmhhbmRsZXNbaV0uaGtleQk9IGhrZXk7CglvcGVuaGFuZGxlc1tpXS5hY2Nlc3NtYXNrPSBhY2Nlc3NtYXNrOwoJbnJvZm9wZW5oYW5kbGVzKys7Cn0KCnN0YXRpYyBMUEtFWVNUUlVDVApnZXRfaGFuZGxlKEhLRVkgaGtleSkgewoJaW50CWk7CgoJZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQoJCWlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQoJCQlyZXR1cm4gb3BlbmhhbmRsZXNbaV0ubHBrZXk7CglkcHJpbnRmX3JlZyhzdGRkZWIsImdldF9oYW5kbGU6RGlkbid0IGZpbmQgaGFuZGxlICVseD9cbiIsKExPTkcpaGtleSk7CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQKcmVtb3ZlX2hhbmRsZShIS0VZIGhrZXkpIHsKCWludAlpOwoKCWZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykKCQlpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkKCQkJYnJlYWs7CglpZiAoaT09bnJvZm9wZW5oYW5kbGVzKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJyZW1vdmVfaGFuZGxlOkRpZG4ndCBmaW5kIGhhbmRsZSAlMDh4P1xuIixoa2V5KTsKCQlyZXR1cm47Cgl9CgltZW1jcHkoCW9wZW5oYW5kbGVzK2ksCgkJb3BlbmhhbmRsZXMraSsxLAoJCXNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCgkpOwoJb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKCW5yb2ZvcGVuaGFuZGxlcy0tOwoJcmV0dXJuOwp9CgoKLyogZGVidWcgZnVuY3Rpb24sIGNvbnZlcnRzIGEgdW5pY29kZSBpbnRvIGEgc3RhdGljIG1lbW9yeSBhcmVhIAogKiAoc3ViIGZvciB1c2luZyB0d28gc3RhdGljIHN0cmluZ3MsIGluIGNhc2Ugd2UgbmVlZCB0aGVtIGluIGEgc2luZ2xlIGNhbGwpCiAqLwpMUFNUUgpXMkMoTFBDV1NUUiB4LGludCBzdWIpIHsKCXN0YXRpYwlMUFNUUgl1bmljb2RlZGVidWdbMl09e05VTEwsTlVMTH07CglpZiAoeD09TlVMTCkKCQlyZXR1cm4gIjxOVUxMPiI7CglpZiAoc3ViIT0wICYmIHN1YiE9MSkKCQlyZXR1cm4gIjxXMkM6YmFkIHN1Yj4iOwoJaWYgKHVuaWNvZGVkZWJ1Z1tzdWJdKSBIZWFwRnJlZSggU3lzdGVtSGVhcCwgMCwgdW5pY29kZWRlYnVnW3N1Yl0gKTsKCXVuaWNvZGVkZWJ1Z1tzdWJdID0gSEVBUF9zdHJkdXBXdG9BKCBTeXN0ZW1IZWFwLCAwLCB4ICk7CglyZXR1cm4gdW5pY29kZWRlYnVnW3N1Yl07Cn0KCnN0YXRpYyBMUEtFWVNUUlVDVApsb29rdXBfaGtleShIS0VZIGhrZXkpIHsKCXN3aXRjaCAoaGtleSkgewoJY2FzZSAweDAwMDAwMDAwOgoJY2FzZSAweDAwMDAwMDAxOgoJY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDoKCQlyZXR1cm4ga2V5X2NsYXNzZXNfcm9vdDsKCWNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CgkJcmV0dXJuIGtleV9jdXJyZW50X3VzZXI7CgljYXNlIEhLRVlfTE9DQUxfTUFDSElORToKCQlyZXR1cm4ga2V5X2xvY2FsX21hY2hpbmU7CgljYXNlIEhLRVlfVVNFUlM6CgkJcmV0dXJuIGtleV91c2VyczsKCWNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgoJCXJldHVybiBrZXlfcGVyZm9ybWFuY2VfZGF0YTsKCWNhc2UgSEtFWV9EWU5fREFUQToKCQlyZXR1cm4ga2V5X2R5bl9kYXRhOwoJY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgoJCXJldHVybiBrZXlfY3VycmVudF9jb25maWc7CglkZWZhdWx0OgoJCWRwcmludGZfcmVnKHN0ZGRlYiwibG9va3VwX2hrZXkoJWx4KSwgc3BlY2lhbCBrZXkhXG4iLAoJCQkoTE9ORyloa2V5CgkJKTsKCQlyZXR1cm4gZ2V0X2hhbmRsZShoa2V5KTsKCX0KCS8qTk9UUkVBQ0hFRCovCn0KCi8qIAogKiBzcGxpdHMgdGhlIHVuaWNvZGUgc3RyaW5nICd3cCcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzLgogKiB0aGUgYXJyYXkgaXMgYWxsb2NhdGVkIGJ5IHRoaXMgZnVuY3Rpb24uIAogKiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgd2lsbCBiZSBzdG9yZWQgaW4gJ3dwYycKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKi8Kc3RhdGljIHZvaWQKc3BsaXRfa2V5cGF0aChMUENXU1RSIHdwLExQV1NUUiAqKndwdixpbnQgKndwYykgewoJaW50CWksaixsZW47CglMUFdTVFIJd3M7CgoJd3MJPSBIRUFQX3N0cmR1cFcoIFN5c3RlbUhlYXAsIDAsIHdwICk7Cgkqd3BjCT0gMTsKCWZvciAoaT0wO3dzW2ldO2krKykgewoJCWlmICh3c1tpXT09J1xcJykgewoJCQl3c1tpXT0wOwoJCQkoKndwYykrKzsKCQl9Cgl9CglsZW4JPSBpOwoJKndwdgk9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwoJKCp3cHYpWzBdPSB3czsKCWoJPSAxOwoJZm9yIChpPTE7aTxsZW47aSsrKQoJCWlmICh3c1tpLTFdPT0wKQoJCQkoKndwdilbaisrXT13cytpOwoJKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRIIEhlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHNbMF0pO0hlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHMpOwoKLyoKICogU2hlbGwgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBrZXlzLiAKICovCnZvaWQgU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCk7CnZvaWQKU0hFTExfSW5pdCgpIHsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCglIS0VZCWNsX3JfaGtleSxjX3VfaGtleTsKI2RlZmluZSBBRERfUk9PVF9LRVkoeHgpIFwKCXh4ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCW1lbXNldCh4eCwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTtcCgl4eC0+a2V5bmFtZT0gc3RyZHVwQTJXKCI8c2hvdWxkX25vdF9hcHBlYXJfYW55d2hlcmU+Iik7CgoJQUREX1JPT1RfS0VZKGtleV9sb2NhbF9tYWNoaW5lKTsKCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcU09GVFdBUkVcXENsYXNzZXMiLCZjbF9yX2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJZnByaW50ZihzdGRlcnIsImNvdWxkbid0IGNyZWF0ZSBIS0VZX0xPQ0FMX01BQ0hJTkVcXFNPRlRXQVJFXFxDbGFzc2VzLiBUaGlzIGlzIGltcG9zc2libGUuXG4iKTsKCQlleGl0KDEpOwoJfQoJa2V5X2NsYXNzZXNfcm9vdCA9IGxvb2t1cF9oa2V5KGNsX3JfaGtleSk7CgoJQUREX1JPT1RfS0VZKGtleV91c2Vycyk7CgojaWYgMAoJLyogRklYTUU6IGxvYWQgYWxsIHVzZXJzIGFuZCB0aGVpciByZXNwLiBwd2QtPnB3X2Rpci8ud2luZS91c2VyLnJlZyAKCSAqCSAgKGxhdGVyLCB3aGVuIGEgd2luMzIgcmVnaXN0cnkgZWRpdGluZyB0b29sIGJlY29tZXMgYXZhaWwuKQoJICovCgl3aGlsZSAocHdkPWdldHB3ZW50KCkpIHsKCQlpZiAocHdkLT5wd19uYW1lID09IE5VTEwpCgkJCWNvbnRpbnVlOwoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMscHdkLT5wd19uYW1lLCZjX3VfaGtleSk7CgkJUmVnQ2xvc2VLZXkoY191X2hrZXkpOwoJfQojZW5kaWYKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkICYmIHB3ZC0+cHdfbmFtZSkgewoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMscHdkLT5wd19uYW1lLCZjX3VfaGtleSk7CgkJa2V5X2N1cnJlbnRfdXNlciA9IGxvb2t1cF9oa2V5KGNfdV9oa2V5KTsKCX0gZWxzZSB7CgkJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X3VzZXIpOwoJfQoJQUREX1JPT1RfS0VZKGtleV9wZXJmb3JtYW5jZV9kYXRhKTsKCUFERF9ST09UX0tFWShrZXlfY3VycmVudF9jb25maWcpOwoJQUREX1JPT1RfS0VZKGtleV9keW5fZGF0YSk7CiN1bmRlZiBBRERfUk9PVF9LRVkKCVNIRUxMX1N0YXJ0dXBSZWdpc3RyeSgpOwp9CgoKdm9pZApTSEVMTF9TdGFydHVwUmVnaXN0cnkoKSB7CglIS0VZCWhrZXkseGhrZXk9MDsKCUZJTEUJKkY7CgljaGFyCWJ1ZlsyMDBdLGNwdWJ1ZlsyMDBdOwoKCVJlZ0NyZWF0ZUtleTE2KEhLRVlfRFlOX0RBVEEsIlxcUGVyZlN0YXRzXFxTdGF0RGF0YSIsJnhoa2V5KTsKCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKICAgICAgICB4aGtleSA9IDA7CglSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW1cXENlbnRyYWxQcm9jZXNzb3IiLCZoa2V5KTsKI2lmZGVmIGxpbnV4CglGPWZvcGVuKCIvcHJvYy9jcHVpbmZvIiwiciIpOwoJaWYgKEYpIHsKCQlpbnQJcHJvY25yPS0xLHg7CgkJd2hpbGUgKE5VTEwhPWZnZXRzKGJ1ZiwyMDAsRikpIHsKCQkJaWYgKHNzY2FuZihidWYsInByb2Nlc3Nvclx0OiAlZCIsJngpKSB7CgkJCQlzcHJpbnRmKGJ1ZiwiJWQiLHgpOwoJCQkJaWYgKHhoa2V5KQoJCQkJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCQkJCXByb2Nucj14OwoJCQkJUmVnQ3JlYXRlS2V5MTYoaGtleSxidWYsJnhoa2V5KTsKCQkJfQoJCQlpZiAoc3NjYW5mKGJ1ZiwiY3B1XHRcdDogJXMiLGNwdWJ1ZikpIHsKCQkJCXNwcmludGYoYnVmLCJDUFUgJXMiLGNwdWJ1Zik7CgkJCQlpZiAoeGhrZXkpCgkJCQkJUmVnU2V0VmFsdWVFeDMyQSh4aGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKTsKCQkJfQoJCX0KCQlmY2xvc2UoRik7Cgl9CglpZiAoeGhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CiNlbHNlCgkvKiBGSVhNRSAqLwoJUmVnQ3JlYXRlS2V5MTYoaGtleSwiMCIsJnhoa2V5KTsKCVJlZ1NldFZhbHVlRXgzMkEoeGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJDUFUgMzg2IixzdHJsZW4oIkNQVSAzODYiKSk7CiNlbmRpZgoJUmVnT3BlbktleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiXFxIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbSIsJmhrZXkpOwoJUmVnU2V0VmFsdWVFeDMyQShoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiU3lzdGVtVHlwZSBXSU5FIixzdHJsZW4oIlN5c3RlbVR5cGUgV0lORSIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8JCQkJCQkKCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmeGhrZXkpOwoJCVJlZ1NldFZhbHVlRXgxNih4aGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJfQp9Ci8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwpzdGF0aWMgaW50Cl9zYXZlX2NoZWNrX3RhaW50ZWQoTFBLRVlTVFJVQ1QgbHBrZXkpIHsKCWludAkJdGFpbnRlZDsKCglpZiAoIWxwa2V5KQoJCXJldHVybiAwOwoJaWYgKGxwa2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkKCQl0YWludGVkID0gMTsKCWVsc2UKCQl0YWludGVkID0gMDsKCXdoaWxlIChscGtleSkgewoJCWlmIChfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKSkgewoJCQlscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCQl0YWludGVkID0gMTsKCQl9CgkJbHBrZXkJPSBscGtleS0+bmV4dDsKCX0KCXJldHVybiB0YWludGVkOwp9CgpzdGF0aWMgdm9pZApfc2F2ZV9VU1RSSU5HKEZJTEUgKkYsTFBXU1RSIHdzdHIsaW50IGVzY2FwZWVxKSB7CglMUFdTVFIJczsKCWludAlkb2VzY2FwZTsKCglpZiAod3N0cj09TlVMTCkKCQlyZXR1cm47CglzPXdzdHI7Cgl3aGlsZSAoKnMpIHsKCQlkb2VzY2FwZT0wOwoJCWlmICgqcz4weGZmKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXG4nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKGVzY2FwZWVxICYmICpzPT0nPScpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcXCcpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwdXRjKCpzLEYpOyAvKiBpZiBcXCB0aGVuIHB1dCBpdCB0d2ljZS4gKi8KCQlpZiAoZG9lc2NhcGUpCgkJCWZwcmludGYoRiwiXFx1JTA0eCIsKigodW5zaWduZWQgc2hvcnQqKXMpKTsKCQllbHNlCgkJCWZwdXRjKCpzLEYpOwoJCXMrKzsKCX0KfQoKc3RhdGljIGludApfc2F2ZXN1YmtleShGSUxFICpGLExQS0VZU1RSVUNUIGxwa2V5LGludCBsZXZlbCxpbnQgYWxsKSB7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCgxPDx2YWwtPnR5cGUpICYgVU5JQ09OVk1BU0spCgkJCQkJX3NhdmVfVVNUUklORyhGLChMUFdTVFIpdmFsLT5kYXRhLDApOwoJCQkJZWxzZQoJCQkJCWZvciAoaj0wO2o8dmFsLT5sZW47aisrKQoJCQkJCQlmcHJpbnRmKEYsIiUwMngiLCooKHVuc2lnbmVkIGNoYXIqKXZhbC0+ZGF0YStqKSk7CgkJCQlmcHV0cygiXG4iLEYpOwoJCQl9CgkJCS8qIGRlc2NlbmQgcmVjdXJzaXZlbHkgKi8KCQkJaWYgKCFfc2F2ZXN1YmtleShGLGxweGtleS0+bmV4dHN1YixsZXZlbCsxLGFsbCkpCgkJCQlyZXR1cm4gMDsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCXJldHVybiAxOwp9CgpzdGF0aWMgaW50Cl9zYXZlc3VicmVnKEZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IGFsbCkgewoJZnByaW50ZihGLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWRcbiIsUkVHSVNUUllfU0FWRV9WRVJTSU9OKTsKCV9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpOwoJcmV0dXJuIF9zYXZlc3Via2V5KEYsbHBrZXktPm5leHRzdWIsMCxhbGwpOwp9CgpzdGF0aWMgQk9PTDMyCl9zYXZlcmVnKExQS0VZU1RSVUNUIGxwa2V5LGNoYXIgKmZuLGludCBhbGwpIHsKCUZJTEUJKkY7CgoJRj1mb3BlbihmbiwidyIpOwoJaWYgKEY9PU5VTEwpIHsKCQlmcHJpbnRmKHN0ZGRlYixfX0ZJTEVfXyI6X3NhdmVyZWc6Q291bGRuJ3Qgb3BlbiAlcyBmb3Igd3JpdGluZzogJXNcbiIsCgkJCWZuLHN0cmVycm9yKGVycm5vKQoJCSk7CgkJcmV0dXJuIEZBTFNFOwoJfQoJaWYgKCFfc2F2ZXN1YnJlZyhGLGxwa2V5LGFsbCkpIHsKCQlmY2xvc2UoRik7CgkJdW5saW5rKGZuKTsKCQlmcHJpbnRmKHN0ZGRlYixfX0ZJTEVfXyI6X3NhdmVyZWc6RmFpbGVkIHRvIHNhdmUga2V5cywgcGVyaGFwcyBubyBtb3JlIGRpc2tzcGFjZSBmb3IgJXM/XG4iLGZuKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglmY2xvc2UoRik7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCnZvaWQKU0hFTExfU2F2ZVJlZ2lzdHJ5KCkgewoJY2hhcgkqZm47CglzdHJ1Y3QJcGFzc3dkCSpwd2Q7CgljaGFyCWJ1Zls0XTsKCUhLRVkJaGtleTsKCWludAlhbGw7CgoJYWxsPTA7CglpZiAoUmVnT3BlbktleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCX0gZWxzZSB7CgkJRFdPUkQgbGVuLGp1bmssdHlwZTsKCgkJbGVuPTQ7CgkJaWYgKAkoRVJST1JfU1VDQ0VTUyE9UmVnUXVlcnlWYWx1ZUV4MzJBKAoJCQkJaGtleSwKCQkJCVZBTF9TQVZFVVBEQVRFRCwKCQkJCSZqdW5rLAoJCQkJJnR5cGUsCgkJCQlidWYsCgkJCQkmbGVuCgkJCSkpfHwgKHR5cGUhPVJFR19TWikKCQkpCgkJCXN0cmNweShidWYsInllcyIpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQoJaWYgKGxzdHJjbXBpMzJBKGJ1ZiwieWVzIikpCgkJYWxsPTE7Cglwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJaWYgKHB3ZCE9TlVMTCAmJiBwd2QtPnB3X2RpciE9TlVMTCkKICAgICAgICB7CiAgICAgICAgICAgICAgICBjaGFyICp0bXA7CgoJCWZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4ocHdkLT5wd19kaXIpICsgc3RybGVuKFdJTkVfUFJFRklYKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSArIDIgKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCk7CgkJLyogY3JlYXRlIHRoZSBkaXJlY3RvcnkuIGRvbid0IGNhcmUgYWJvdXQgZXJyb3Jjb2Rlcy4gKi8KCQlta2RpcihmbiwwNzU1KTsgLyogZHJ3eHIteHIteCAqLwoJCXN0cmNhdChmbiwiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKCQlzdHJjcHkodG1wLGZuKTtzdHJjYXQodG1wLCIudG1wIik7CgkJaWYgKF9zYXZlcmVnKGtleV9jdXJyZW50X3VzZXIsdG1wLGFsbCkpIHsKCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewoJCQkJcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CgkJCQl1bmxpbmsodG1wKTsKCQkJfQoJCX0KCQlmcmVlKHRtcCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcoa2V5X2xvY2FsX21hY2hpbmUsdG1wLGFsbCkpIHsKCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewoJCQkJcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CgkJCQl1bmxpbmsodG1wKTsKCQkJfQoJCX0KCQlmcmVlKHRtcCk7CgkJZnJlZShmbik7Cgl9IGVsc2UKCQlmcHJpbnRmKHN0ZGVyciwiU0hFTExfU2F2ZVJlZ2lzdHJ5OmZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKiBMT0FEIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgTFBLRVlTVFJVQ1QKX2ZpbmRfb3JfYWRkX2tleShMUEtFWVNUUlVDVCBscGtleSxMUFdTVFIga2V5bmFtZSkgewoJTFBLRVlTVFJVQ1QJbHB4a2V5LCpscGxwa2V5OwoKCWxwbHBrZXk9ICYobHBrZXktPm5leHRzdWIpOwoJbHB4a2V5CT0gKmxwbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKCFsc3RyY21waTMyVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCnN0YXRpYyB2b2lkCl9maW5kX29yX2FkZF92YWx1ZSgKCUxQS0VZU1RSVUNUIGxwa2V5LExQV1NUUiBuYW1lLERXT1JEIHR5cGUsTFBCWVRFIGRhdGEsRFdPUkQgbGVuLAoJRFdPUkQgbGFzdG1vZGlmaWVkCikgewoJTFBLRVlWQUxVRQl2YWw9TlVMTDsKCWludAkJaTsKCglmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykgewoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJaWYgKG5hbWU9PU5VTEwpIHsKCQkJaWYgKHZhbC0+bmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJCX0gZWxzZSB7CgkJCWlmICgJdmFsLT5uYW1lIT1OVUxMICYmIAoJCQkJIWxzdHJjbXBpMzJXKHZhbC0+bmFtZSxuYW1lKQoJCQkpCgkJCQlicmVhazsKCQl9Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0geHJlYWxsb2MoCgkJCWxwa2V5LT52YWx1ZXMsCgkJCSgrK2xwa2V5LT5ucm9mdmFsdWVzKSpzaXplb2YoS0VZVkFMVUUpCgkJKTsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCW1lbXNldCh2YWwsJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCQl2YWwtPm5hbWUgPSBuYW1lOwoJfSBlbHNlIHsKCQlpZiAobmFtZSkKCQkJZnJlZShuYW1lKTsKCX0KCWlmICh2YWwtPmxhc3Rtb2RpZmllZDxsYXN0bW9kaWZpZWQpIHsKCQl2YWwtPmxhc3Rtb2RpZmllZD1sYXN0bW9kaWZpZWQ7CgkJdmFsLT50eXBlID0gdHlwZTsKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IApfd2luZV9yZWFkX2xpbmUoRklMRSAqRixjaGFyICoqYnVmLGludCAqbGVuKSB7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCSpidWYJPSB4cmVhbGxvYygqYnVmLCpsZW4qMik7CgkJCQljdXJyZWFkCT0gKmJ1ZiArIGN1cm9mZjsKCQkJCW15bGVuCT0gKmxlbjsJLyogd2UgZmlsbGVkIHVwIHRoZSBidWZmZXIgYW5kIAoJCQkJCQkgKiBnb3QgbmV3ICcqbGVuJyBieXRlcyB0byBmaWxsCgkJCQkJCSAqLwoJCQkJKmxlbgk9ICpsZW4gKiAyOwoJCQl9IGVsc2UgewoJCQkJKnM9J1wwJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCS8qIHRocm93IGF3YXkgY29tbWVudHMgKi8KCQlpZiAoKipidWY9PScjJyB8fCAqKmJ1Zj09JzsnKSB7CgkJCWN1cnJlYWQJPSAqYnVmOwoJCQlteWxlbgk9ICpsZW47CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocykgCS8qIGdvdCBlbmQgb2YgbGluZSAqLwoJCQlicmVhazsKCX0KCXJldHVybiAxOwp9CgovKiBjb252ZXJ0cyBhIGNoYXIqIGludG8gYSBVTklDT0RFIHN0cmluZyAodXAgdG8gYSBzcGVjaWFsIGNoYXIpCiAqIGFuZCByZXR1cm5zIHRoZSBwb3NpdGlvbiBleGFjdGx5IGFmdGVyIHRoYXQgc3RyaW5nCiAqLwpzdGF0aWMgY2hhcioKX3dpbmVfcmVhZF9VU1RSSU5HKGNoYXIgKmJ1ZixMUFdTVFIgKnN0cikgewoJY2hhcgkqczsKCUxQV1NUUgl3czsKCgkvKiByZWFkIHVwIHRvICI9IiBvciAiXDAiIG9yICJcbiIgKi8KCXMJPSBidWY7CglpZiAoKnMgPT0gJz0nKSB7CgkJLyogZW1wdHkgc3RyaW5nIGlzIHRoZSB3aW4zLjEgZGVmYXVsdCB2YWx1ZShOVUxMKSovCgkJKnN0cgk9IE5VTEw7CgkJcmV0dXJuIHM7Cgl9Cgkqc3RyCT0gKExQV1NUUil4bWFsbG9jKDIqc3RybGVuKGJ1ZikrMik7Cgl3cwk9ICpzdHI7Cgl3aGlsZSAoKnMgJiYgKCpzIT0nXG4nKSAmJiAoKnMhPSc9JykpIHsKCQlpZiAoKnMhPSdcXCcpCgkJCSp3cysrPSooKHVuc2lnbmVkIGNoYXIqKXMrKyk7CgkJZWxzZSB7CgkJCXMrKzsKCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrKz0nXFwnOwoJCQkJcysrOwoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCpzIT0ndScpIHsKCQkJCWZwcmludGYoc3RkZXJyLCJfd2luZV9yZWFkX1VTVFJJTkc6Tm9uIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIFxcJWMgZm91bmQgaW4gfCVzfFxuIiwqcyxidWYpOwoJCQkJKndzKys9J1xcJzsKCQkJCSp3cysrPSpzKys7CgkJCX0gZWxzZSB7CgkJCQljaGFyCXhidWZbNV07CgkJCQlpbnQJd2M7CgoJCQkJcysrOwoJCQkJbWVtY3B5KHhidWYscyw0KTt4YnVmWzRdPSdcMCc7CgkJCQlpZiAoIXNzY2FuZih4YnVmLCIleCIsJndjKSkKCQkJCQlmcHJpbnRmKHN0ZGVyciwiX3dpbmVfcmVhZF9VU1RSSU5HOnN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJd3MJPSAqc3RyOwoJKnN0cgk9IHN0cmR1cFcoKnN0cik7CglmcmVlKHdzKTsKCXJldHVybiBzOwp9CgpzdGF0aWMgaW50Cl93aW5lX2xvYWRzdWJrZXkoCglGSUxFICpGLExQS0VZU1RSVUNUIGxwa2V5LGludCBsZXZlbCxjaGFyICoqYnVmLGludCAqYnVmbGVuLGludCBvcHRmbGFnCikgewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgoJbHBrZXktPmZsYWdzIHw9IG9wdGZsYWc7CgoJLyogZ29vZC4gd2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCglscHhrZXkJPSBOVUxMOwoJd2hpbGUgKDEpIHsKCQlpPTA7cz0qYnVmOwoJCXdoaWxlICgqcz09J1x0JykgewoJCQlzKys7CgkJCWkrKzsKCQl9CgkJaWYgKGk+bGV2ZWwpIHsKCQkJaWYgKGxweGtleT09TlVMTCkgewoJCQkJZnByaW50ZihzdGRlcnIsIl9sb2FkX3N1YmtleTpHb3QgYSBzdWJoaWVyYXJjaHkgd2l0aG91dCByZXNwLiBrZXk/XG4iKTsKCQkJCXJldHVybiAwOwoJCQl9CgkJCV93aW5lX2xvYWRzdWJrZXkoRixscHhrZXksbGV2ZWwrMSxidWYsYnVmbGVuLG9wdGZsYWcpOwoJCQljb250aW51ZTsKCQl9CgkJLyogbGV0IHRoZSBjYWxsZXIgaGFuZGxlIHRoaXMgbGluZSAqLwoJCWlmIChpPGxldmVsIHx8ICoqYnVmPT0nXDAnKQoJCQlyZXR1cm4gMTsKCgkJLyogaXQgY2FuIGJlOiBhIHZhbHVlIG9yIGEga2V5bmFtZS4gUGFyc2UgdGhlIG5hbWUgZmlyc3QgKi8KCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLCZuYW1lKTsKCgkJLyogc3dpdGNoKCkgZGVmYXVsdDogaGFjayB0byBhdm9pZCBnb3RvcyAqLwoJCXN3aXRjaCAoMCkgewoJCWRlZmF1bHQ6CgkJCWlmICgqcz09J1wwJykgewoJCQkJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgkJCX0gZWxzZSB7CgkJCQlMUEJZVEUJCWRhdGE7CgkJCQlpbnQJCWxlbixsYXN0bW9kaWZpZWQsdHlwZTsKCgkJCQlpZiAoKnMhPSc9JykgewoJCQkJCWZwcmludGYoc3RkZXJyLCJfd2luZV9sb2FkX3N1YmtleTp1bmV4cGVjdGVkIGNoYXJhY3RlcjogJWNcbiIsKnMpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJcysrOwoJCQkJaWYgKDIhPXNzY2FuZihzLCIlZCwlZCwiLCZ0eXBlLCZsYXN0bW9kaWZpZWQpKSB7CgkJCQkJZnByaW50ZihzdGRlcnIsIl93aW5lX2xvYWRfc3Via2V5OiBoYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICgoMTw8dHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsKExQV1NUUiopJmRhdGEpOwoJCQkJCWlmIChkYXRhKQoJCQkJCQlsZW4gPSBsc3RybGVuMzJXKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJCWVsc2UJCgkJCQkJCWxlbiA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCWxlbj1zdHJsZW4ocykvMjsKCQkJCQlkYXRhID0gKExQQllURSl4bWFsbG9jKGxlbisxKTsKCQkJCQlmb3IgKGk9MDtpPGxlbjtpKyspIHsKCQkJCQkJZGF0YVtpXT0wOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXT0oKnMtJzAnKTw8NDsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV09KCpzLSdhJyk8PDQ7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nQScpPDw0OwoJCQkJCQlzKys7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldfD0qcy0nMCc7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nYSc7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nQSc7CgkJCQkJCXMrKzsKCQkJCQl9CgkJCQl9CgkJCQlfZmluZF9vcl9hZGRfdmFsdWUobHBrZXksbmFtZSx0eXBlLGRhdGEsbGVuLGxhc3Rtb2RpZmllZCk7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJcmV0dXJuIDE7Cgl9CglyZXR1cm4gMTsKfQoKc3RhdGljIGludApfd2luZV9sb2Fkc3VicmVnKEZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IG9wdGZsYWcpIHsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsX19GSUxFX18iOl93aW5lX2xvYWRzdWJyZWc6T2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixscGtleSwwLCZidWYsJmJ1ZmxlbixvcHRmbGFnKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUoYnVmKTsKCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZApfd2luZV9sb2FkcmVnKExQS0VZU1RSVUNUIGxwa2V5LGNoYXIgKmZuLGludCBvcHRmbGFnKSB7CglGSUxFCSpGOwoKCUY9Zm9wZW4oZm4sInJiIik7CglpZiAoRj09TlVMTCkgewoJCWRwcmludGZfcmVnKHN0ZGRlYixfX0ZJTEVfXyI6Q291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsCgkJCWZuLHN0cmVycm9yKGVycm5vKQoJCSk7CgkJcmV0dXJuOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3VicmVnKEYsbHBrZXksb3B0ZmxhZykpIHsKCQlmY2xvc2UoRik7CgkJdW5saW5rKGZuKTsKCQlyZXR1cm47Cgl9CglmY2xvc2UoRik7Cn0KCnN0YXRpYyB2b2lkCl9jb3B5X3JlZ2lzdHJ5KExQS0VZU1RSVUNUIGZyb20sTFBLRVlTVFJVQ1QgdG8pIHsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJajsKCUxQS0VZVkFMVUUJdmFsZnJvbTsKCglmcm9tPWZyb20tPm5leHRzdWI7Cgl3aGlsZSAoZnJvbSkgewoJCWxweGtleSA9IF9maW5kX29yX2FkZF9rZXkodG8sc3RyZHVwVyhmcm9tLT5rZXluYW1lKSk7CgoJCWZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIHsKCQkJTFBXU1RSCW5hbWU7CgkJCUxQQllURQlkYXRhOwoKCQkJdmFsZnJvbSA9IGZyb20tPnZhbHVlcytqOwoJCQluYW1lPXZhbGZyb20tPm5hbWU7CgkJCWlmIChuYW1lKSBuYW1lPXN0cmR1cFcobmFtZSk7CgkJCWRhdGE9KExQQllURSltYWxsb2ModmFsZnJvbS0+bGVuKTsKCQkJbWVtY3B5KGRhdGEsdmFsZnJvbS0+ZGF0YSx2YWxmcm9tLT5sZW4pOwoKCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkJbHB4a2V5LAoJCQkJbmFtZSwKCQkJCXZhbGZyb20tPnR5cGUsCgkJCQlkYXRhLAoJCQkJdmFsZnJvbS0+bGVuLAoJCQkJdmFsZnJvbS0+bGFzdG1vZGlmaWVkCgkJCSk7CgkJfQoJCV9jb3B5X3JlZ2lzdHJ5KGZyb20sbHB4a2V5KTsKCQlmcm9tID0gZnJvbS0+bmV4dDsKCX0KfQoKLyogV0lORE9XUyA5NSBSRUdJU1RSWSBMT0FERVIgKi8KLyogCiAqIFN0cnVjdHVyZSBvZiBhIHdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlLgogKiBtYWluIGhlYWRlcjoKICogMCA6CSJDUkVHIgktIG1hZ2ljCiAqIDQgOglEV09SRCB2ZXJzaW9uCiAqIDggOglEV09SRCBvZmZzZXRfb2ZfUkdEQl9wYXJ0CiAqIDBDLi4xRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICoKICogMjA6IFJHS05fc2VjdGlvbjoKICogICBoZWFkZXI6CiAqIAkwIDoJCSJSR0tOIgktIG1hZ2ljCiAqIAk0Li4weDFCOiAJPyAoZmlsbCBpbikKICogICAgICAweDIwIC4uLiBvZmZzZXRfb2ZfUkdEQl9wYXJ0OiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmVzCiAqCiAqICAgRGlzayBLZXkgRW50cnkgU3RydWN0dXJlOgogKgkwMDogRFdPUkQJLSB1bmtub3duCiAqCTA0OiBEV09SRAktIHVua25vd24KICoJMDg6IERXT1JECS0gdW5rbm93biwgYnV0IHVzdWFsbHkgMHhGRkZGRkZGRiBvbiB3aW45NSBzeXN0ZW1zCiAqCTBDOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBQcmV2aW91c0xldmVsIEtleS4KICoJMTA6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgU3VibGV2ZWwgS2V5LgogKgkxNDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBLZXkgKG9uIHNhbWUgbGV2ZWwpLgogKiBES0VQPjE4OiBXT1JECS0gTnIsIExvdyBTaWduaWZpY2FudCBwYXJ0LgogKgkxQTogV09SRAktIE5yLCBIaWdoIFNpZ25pZmljYW50IHBhcnQuCiAqCiAqIFRoZSBkaXNrIGFkZHJlc3MgYWx3YXlzIHBvaW50cyB0byB0aGUgbnIgcGFydCBvZiB0aGUgcHJldmlvdXMga2V5IGVudHJ5IAogKiBvZiB0aGUgcmVmZXJlbmNlZCBrZXkuIERvbid0IGFzayBtZSB3aHksIG9yIGV2ZW4gaWYgSSBnb3QgdGhpcyBjb3JyZWN0CiAqIGZyb20gc3RhcmluZyBhdCAxa2cgb2YgaGV4ZHVtcHMuIChES0VQKQogKgogKiBUaGUgbnVtYmVyIG9mIHRoZSBlbnRyeSBpcyB0aGUgbG93IGJ5dGUgb2YgdGhlIExvdyBTaWduaWZpY2FudCBQYXJ0IG9yZWQKICogd2l0aCAweDEwMCAqIChsb3cgYnl0ZSBvZiB0aGUgSGlnaCBTaWduaWZpY2FudCBwYXJ0KQogKiAoQyBleHByZXNzaW9uIDogbnIgPSAobnJMUyAmIDB4RkYpIHwgKChuckhTICYweEZGKTw8OCkpCiAqCiAqIFRoZXJlIGFyZSB0d28gbWlub3IgY29ycmVjdGlvbnMgdG8gdGhlIHBvc2l0aW9uIG9mIHRoYXQgc3RydWN0dXJlLgogKiAxLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHgwMTQgb3IgeHh4MDE4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byB4eHgwMWMgQU5EIAogKiAgICB0aGUgREtFIHJlcmVhZCBmcm9tIHRoZXJlLgogKiAyLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHhGRnggaXQgd2lsbCBiZSBhbGlnbmVkIHRvICh4eHgrMSkwMDAuCiAqIChGSVhNRTogc2xpZ2h0bHkgYmV0dGVyIGV4cGxhbmF0aW9uIG5lZWRlZCBoZXJlKQogKgogKiBSR0RCX3NlY3Rpb246CiAqIAkwMDoJCSJSR0RCIgktIG1hZ2ljCiAqCTA0OiBEV09SRAlvZmZzZXQgdG8gbmV4dCBSR0RCIHNlY3Rpb24gKHBlcmhhcHMgV09SRCkKICoJMDguLi4xRjoJPwogKgkyMC4uLi4uOglkaXNrIGtleXMKICoKICogZGlzayBrZXk6CiAqIAkwMDogCURXT1JECW5leHRrZXlvZmZzZXQJLSBvZmZzZXQgdG8gdGhlIG5leHQgZGlzayBrZXkgc3RydWN0dXJlCiAqCTA4OiAJV09SRAluckxTCQktIGxvdyBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBBOiAJV09SRAluckhTCQktIGhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQzogCURXT1JECWJ5dGVzdXNlZAktIGJ5dGVzIHVzZWQgaW4gdGhpcyBzdHJ1Y3R1cmUuCiAqCTEwOiAJV09SRAluYW1lX2xlbgktIGxlbmd0aCBvZiBuYW1lIGluIGJ5dGVzLiB3aXRob3V0IFwwCiAqCTEyOiAJV09SRAlucl9vZl92YWx1ZXMJLSBudW1iZXIgb2YgdmFsdWVzLgogKgkxNDogCWNoYXIJbmFtZVtuYW1lX2xlbl0JLSBuYW1lIHN0cmluZy4gTm8gXDAuCiAqCTE0K25hbWVfbGVuOiBkaXNrIHZhbHVlcwogKgluZXh0a2V5b2Zmc2V0OiAuLi4gbmV4dCBkaXNrIGtleQogKgogKiBkaXNrIHZhbHVlOgogKgkwMDoJRFdPUkQJdHlwZQkJLSB2YWx1ZSB0eXBlIChobW0sIGNvdWxkIGJlIFdPUkQgdG9vKQogKgkwNDoJRFdPUkQJCQktIHVua25vd24sIHVzdWFsbHkgMAogKgkwODoJV09SRAluYW1lbGVuCQktIGxlbmd0aCBvZiBOYW1lLiAwIG1lYW5zIG5hbWU9TlVMTAogKgkwQzoJV09SRAlkYXRhbGVuCQktIGxlbmd0aCBvZiBEYXRhLgogKgkxMDoJY2hhcgluYW1lW25hbWVsZW5dCS0gbmFtZSwgbm8gXDAKICoJMTArbmFtZWxlbjogQllURQlkYXRhW2RhdGFsZW5dIC0gZGF0YSwgd2l0aG91dCBcMCBpZiBzdHJpbmcKICoJMTArbmFtZWxlbitkYXRhbGVuOiBuZXh0IHZhbHVlcyBvciBkaXNrIGtleQogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICogcmVwZWF0IHVudGlsIGVuZCBvZiBmaWxlLgogKgogKiBGSVhNRTogdGhpcyBkZXNjcmlwdGlvbiBuZWVkcyBzb21lIHNlcmlvdXMgaGVscCwgeWVzLgogKi8KCnN0cnVjdAlfdzk1a2V5dmFsdWUgewoJdW5zaWduZWQgbG9uZwkJdHlwZTsKCXVuc2lnbmVkIHNob3J0CQlkYXRhbGVuOwoJY2hhcgkJCSpuYW1lOwoJdW5zaWduZWQgY2hhcgkJKmRhdGE7Cgl1bnNpZ25lZCBsb25nCQl4MTsKCWludAkJCWxhc3Rtb2RpZmllZDsKfTsKCnN0cnVjdCAJX3c5NWtleSB7CgljaGFyCQkJKm5hbWU7CglpbnQJCQlucm9mdmFsczsKCXN0cnVjdAlfdzk1a2V5dmFsdWUJKnZhbHVlczsKCXVuc2lnbmVkIGxvbmcJCWRrZWFkZHI7Cgl1bnNpZ25lZCBsb25nIAkJeDE7Cgl1bnNpZ25lZCBsb25nIAkJeDI7Cgl1bnNpZ25lZCBsb25nIAkJeDM7Cgl1bnNpZ25lZCBsb25nIAkJeHgxOwoJc3RydWN0IF93OTVrZXkJCSpwcmV2bHZsOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0c3ViOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0Owp9OwoKLyogZmFzdCBsb29rdXAgdGFibGUgZGtlYWRkci0+bnIgKi8Kc3RydWN0CV93OTVucjJkYSB7Cgl1bnNpZ25lZCBsb25nCQlka2VhZGRyOwoJdW5zaWduZWQgbG9uZwkJbnI7Cn07CgoKc3RhdGljIHZvaWQKX3c5NV93YWxrX3RyZWUoTFBLRVlTVFJVQ1QgbHBrZXksc3RydWN0IF93OTVrZXkgKmtleSkgewoJaW50CQlpOwoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJTFBXU1RSCQluYW1lOwoKCXdoaWxlIChrZXkpIHsKCQlpZiAoa2V5LT5uYW1lID09IE5VTEwpIHsKCQkJZnByaW50ZihzdGRlcnIsIl93OTVfd2Fsa190cmVlOlBsZWFzZSByZXBvcnQ6IGtleSB3aXRoIGRrZWFkZHIgJWx4IG5vdCBsb2FkZWQsIHNraXBwaW5nIGhpZXJhcmNoeVxuIiwKCQkJCWtleS0+ZGtlYWRkcgoJCQkpOwoJCQlyZXR1cm47CgkJfQoJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LHN0cmR1cEEyVyhrZXktPm5hbWUpKTsKCgkJaWYgKGtleS0+bnJvZnZhbHM8MCkgewoJCQkvKiBzaG91bGRuJ3QgaGFwcGVuICovCgkJCWZwcmludGYoc3RkZXJyLCJrZXkgJXMgYWxyZWFkeSBwcm9jZXNzZWQhXG4iLGtleS0+bmFtZSk7CgkJCWtleSA9IGtleS0+bmV4dDsKCQkJY29udGludWU7CgkJfQoJCWZvciAoaT0wO2k8a2V5LT5ucm9mdmFscztpKyspIHsKCQkJTFBCWVRFCWRhdGE7CgkJCWludAlsZW47CgoJCQluYW1lID0gc3RyZHVwQTJXKGtleS0+dmFsdWVzW2ldLm5hbWUpOwoJCQlpZiAoISpuYW1lKSBuYW1lID0gTlVMTDsKCQkJZnJlZShrZXktPnZhbHVlc1tpXS5uYW1lKTsKCgkJCWxlbgk9IGtleS0+dmFsdWVzW2ldLmRhdGFsZW47CgkJCWRhdGEJPSBrZXktPnZhbHVlc1tpXS5kYXRhOwoJCQlpZiAoKDE8PGtleS0+dmFsdWVzW2ldLnR5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCWRhdGEgPSAoQllURSopc3RyZHVwQTJXKGRhdGEpOwoJCQkJbGVuICA9IGxzdHJsZW4zMlcoKExQV1NUUilkYXRhKSoyKzI7CgkJCQlmcmVlKGtleS0+dmFsdWVzW2ldLmRhdGEpOwoJCQl9CgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQlrZXktPnZhbHVlc1tpXS50eXBlLAoJCQkJZGF0YSwKCQkJCWxlbiwKCQkJCWtleS0+dmFsdWVzW2ldLmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlpZiAoa2V5LT52YWx1ZXMpIHsKCQkJZnJlZShrZXktPnZhbHVlcyk7CgkJCWtleS0+dmFsdWVzID0gTlVMTDsKCQl9CgkJa2V5LT5ucm9mdmFscz0ta2V5LT5ucm9mdmFscy0xOwoJCV93OTVfd2Fsa190cmVlKGxweGtleSxrZXktPm5leHRzdWIpOwoJCWtleT1rZXktPm5leHQ7Cgl9Cn0KCi8qIHNtYWxsIGhlbHBlciBmdW5jdGlvbiB0byBhZGp1c3QgYWRkcmVzcyBvZmZzZXQgKGRrZWFkZHJzKSAqLwpzdGF0aWMgdW5zaWduZWQgbG9uZwpfdzk1X2Fkal9kYSh1bnNpZ25lZCBsb25nIGRrZWFkZHIpIHsKCWlmICgoZGtlYWRkciYweEZGRik8MHgwMTgpIHsKCQlpbnQJZGlmZjsKCgkJZGlmZj0weDFDLShka2VhZGRyJjB4RkZGKTsKCQlyZXR1cm4gZGtlYWRkcitkaWZmOwoJfQoJaWYgKCgoZGtlYWRkcisweDFDKSYweEZGRik8MHgxQykgewoJCS8qIHJlYWRqdXN0IHRvIDB4MDAwLAoJCSAqIGJ1dCBPTkxZIGlmIHdlIGFyZSA+MHgxMDAwIGFscmVhZHkKCQkgKi8KCQlpZiAoZGtlYWRkciAmIH4weEZGRikKCQkJcmV0dXJuIGRrZWFkZHIgJiB+MHhGRkY7Cgl9CglyZXR1cm4gZGtlYWRkcjsKfQoKc3RhdGljIGludApfdzk1ZGtlY29tcChzdHJ1Y3QgX3c5NW5yMmRhICphLHN0cnVjdCBfdzk1bnIyZGEgKmIpe3JldHVybiBhLT5ka2VhZGRyLWItPmRrZWFkZHI7fQoKc3RhdGljIHN0cnVjdCBfdzk1a2V5Kgpfdzk1ZGtlbG9va3VwKHVuc2lnbmVkIGxvbmcgZGtlYWRkcixpbnQgbixzdHJ1Y3QgX3c5NW5yMmRhICpucjJkYSxzdHJ1Y3QgX3c5NWtleSAqa2V5cykgewoJaW50CWksb2ZmOwoKCWlmIChka2VhZGRyID09IDB4RkZGRkZGRkYpCgkJcmV0dXJuIE5VTEw7CglpZiAoZGtlYWRkcjwweDIwKQoJCXJldHVybiBOVUxMOwoJZGtlYWRkcj1fdzk1X2Fkal9kYShka2VhZGRyKzB4MWMpOwoJb2ZmID0gKGRrZWFkZHItMHgzYykvMHgxYzsKCWZvciAoaT0wO2k8bjtpKyspCgkJaWYgKG5yMmRhWyhpK29mZiklbl0uZGtlYWRkciA9PSBka2VhZGRyKQoJCQlyZXR1cm4ga2V5cytucjJkYVsoaStvZmYpJW5dLm5yOwoJLyogMHgzQyBoYXBwZW5zIG9mdGVuLCBqdXN0IHJlcG9ydCB1bnVzdWFsIHZhbHVlcyAqLwoJaWYgKGRrZWFkZHIhPTB4M2MpCgkJZHByaW50Zl9yZWcoc3RkZGViLCJzZWFyY2ggaGFzbid0IGZvdW5kIGRrZWFkZHIgJWx4P1xuIixka2VhZGRyKTsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZApfdzk1X2xvYWRyZWcoY2hhciogZm4sTFBLRVlTVFJVQ1QgbHBrZXkpIHsKCS8qIERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZSAoUkdLTiBwYXJ0KSAqLwoJc3RydWN0CWRrZSB7CgkJdW5zaWduZWQgbG9uZwkJeDE7CgkJdW5zaWduZWQgbG9uZwkJeDI7CgkJdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KCQl1bnNpZ25lZCBsb25nCQlwcmV2bHZsOwoJCXVuc2lnbmVkIGxvbmcJCW5leHRzdWI7CgkJdW5zaWduZWQgbG9uZwkJbmV4dDsKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCX07CgkvKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpICovCglzdHJ1Y3QJZGtoIHsKCQl1bnNpZ25lZCBsb25nCQluZXh0a2V5b2ZmOyAKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCQl1bnNpZ25lZCBsb25nCQlieXRlc3VzZWQ7CgkJdW5zaWduZWQgc2hvcnQJCWtleW5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbHVlczsKCQl1bnNpZ25lZCBsb25nCQl4eDE7CgkJLyoga2V5bmFtZSAqLwoJCS8qIGRpc2sga2V5IHZhbHVlcyBvciBub3RoaW5nICovCgl9OwoJLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlICovCglzdHJ1Y3QJZGt2IHsKCQl1bnNpZ25lZCBsb25nCQl0eXBlOwoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxuYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxkYXRhbGVuOwoJCS8qIHZhbG5hbWUsIHZhbGRhdGEgKi8KCX07CglzdHJ1Y3QJX3c5NW5yMmRhIAkqbnIyZGE7CgoJSEZJTEUzMgkJaGZkOwoJaW50CQlsYXN0bW9kaWZpZWQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJbnIscG9zLGksd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQsb2ZmX25leHRfcmdkYjsKCXN0cnVjdAlfdzk1a2V5CSprZXlzOwoJaW50CQlucm9mZGtlczsKCXVuc2lnbmVkIGNoYXIJKmRhdGEsKmN1cmRhdGEsKm5leHRyZ2RiOwoJT0ZTVFJVQ1QJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZkaW5mbzsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIkxvYWRpbmcgV2luOTUgcmVnaXN0cnkgZGF0YWJhc2UgJyVzJ1xuIixmbik7CgloZmQ9T3BlbkZpbGUzMihmbiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmZD09SEZJTEVfRVJST1IzMikKCQlyZXR1cm47CgltYWdpY1s0XT0wOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJDUkVHIikpIHsKCQlmcHJpbnRmKHN0ZGRlYiwiJXMgaXMgbm90IGEgdzk1IHJlZ2lzdHJ5LlxuIixmbik7CgkJcmV0dXJuOwoJfQoJaWYgKDQhPV9scmVhZDMyKGhmZCwmdmVyc2lvbiw0KSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZyZ2Ric2VjdGlvbiw0KSkKCQlyZXR1cm47CglpZiAoLTE9PV9sbHNlZWszMihoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJSR0tOIikpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJXNcbiIsbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4NDAsU0VFS19TRVQpKQoJCXJldHVybjsKCXdoZXJlCT0gMHg0MDsKCWVuZAk9IHJnZGJzZWN0aW9uOwoKCW5yb2Zka2VzID0gKGVuZC13aGVyZSkvc2l6ZW9mKHN0cnVjdCBka2UpKzEwMDsKCWRhdGEgPSAoY2hhciopeG1hbGxvYyhlbmQtd2hlcmUpOwoJaWYgKChlbmQtd2hlcmUpIT1fbHJlYWQzMihoZmQsZGF0YSxlbmQtd2hlcmUpKQoJCXJldHVybjsKCWN1cmRhdGEgPSBkYXRhOwoKCWtleXMgPSAoc3RydWN0IF93OTVrZXkqKXhtYWxsb2MobnJvZmRrZXMgKiBzaXplb2Yoc3RydWN0IF93OTVrZXkpKTsKCW1lbXNldChrZXlzLCdcMCcsbnJvZmRrZXMqc2l6ZW9mKHN0cnVjdCBfdzk1a2V5KSk7CglucjJkYT0gKHN0cnVjdCBfdzk1bnIyZGEqKXhtYWxsb2MobnJvZmRrZXMgKiBzaXplb2Yoc3RydWN0IF93OTVucjJkYSkpOwoJbWVtc2V0KG5yMmRhLCdcMCcsbnJvZmRrZXMqc2l6ZW9mKHN0cnVjdCBfdzk1bnIyZGEpKTsKCglmb3IgKGk9MDtpPG5yb2Zka2VzO2krKykgewoJCXN0cnVjdAlka2UJZGtlOwoJCXVuc2lnbmVkIGxvbmcgCWRrZWFkZHI7CgoJCXBvcz1jdXJkYXRhLWRhdGErMHg0MDsKCQltZW1jcHkoJmRrZSxjdXJkYXRhLHNpemVvZihka2UpKTsKCQljdXJkYXRhKz1zaXplb2YoZGtlKTsKCQluciA9IGRrZS5uckxTICsgKGRrZS5uck1TPDw4KTsKCQlka2VhZGRyPXBvcy00OwoJCWlmICgoZGtlYWRkciYweEZGRik8MHgwMTgpIHsKCQkJaW50CWRpZmY7CgoJCQlkaWZmPTB4MUMtKGRrZWFkZHImMHhGRkYpOwoJCQlka2VhZGRyKz1kaWZmOwoJCQljdXJkYXRhKz1kaWZmLXNpemVvZihka2UpOwoJCQltZW1jcHkoJmRrZSxjdXJkYXRhLHNpemVvZihka2UpKTsKCQkJbnIgPSBka2UubnJMUyArIChka2UubnJNUzw8OCk7CgkJCWN1cmRhdGErPXNpemVvZihka2UpOwoJCX0KCQlpZiAoKChka2VhZGRyKzB4MUMpJjB4RkZGKTwweDFDKSB7CgkJCS8qIHJlYWRqdXN0IHRvIDB4MDAwLAoJCQkgKiBidXQgT05MWSBpZiB3ZSBhcmUgPjB4MTAwMCBhbHJlYWR5CgkJCSAqLwoJCQlpZiAoZGtlYWRkciAmIH4weEZGRikKCQkJCWRrZWFkZHIgPSBka2VhZGRyICYgfjB4RkZGOwoJCX0KCQlpZiAobnI+bnJvZmRrZXMpIHsKCQkJLyogMHhGRkZGRkZGRiBoYXBwZW5zIG9mdGVuLCBqdXN0IHJlcG9ydCB1bnVzdWFsIHZhbHVlcyAqLwoJCQlpZiAobnIhPTB4RkZGRkZGRkYpCgkJCQlkcHJpbnRmX3JlZyhzdGRkZWIsIm5yICVsZCBleGNlZWRzIG5yb2Zka2VzICVkLCBza2lwcGluZy5cbiIsbnIsbnJvZmRrZXMpOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKGtleXNbbnJdLmRrZWFkZHIpIHsKCQkJaW50CXg7CgoJCQlmb3IgKHg9c2l6ZW9mKGRrZSk7eC0tOykKCQkJCWlmICgoKGNoYXIqKSZka2UpW3hdKQoJCQkJCWJyZWFrOwoJCQlpZiAoeD09LTEpCgkJCQlicmVhazsgLyogZmluaXNoZWQgcmVhZGluZyBpZiB3ZSBnb3Qgb25seSAwICovCgkJCWlmIChucikgewoJCQkJaWYgKAkoZGtlLm5leHQhPShsb25nKWtleXNbbnJdLm5leHQpCXx8CgkJCQkJKGRrZS5uZXh0c3ViIT0obG9uZylrZXlzW25yXS5uZXh0c3ViKQl8fAoJCQkJCShka2UucHJldmx2bCE9KGxvbmcpa2V5c1tucl0ucHJldmx2bCkgCgkJCQkpCgkJCQkJZHByaW50Zl9yZWcoc3RkZGViLCJrZXkgZG91YmxlZD8gbnI9JWxkLGtleS0+ZGtlYWRkcj0lbHgsZGtlYWRkcj0lbHhcbiIsbnIsa2V5c1tucl0uZGtlYWRkcixka2VhZGRyKTsKCQkJfQoJCQljb250aW51ZTsKCQl9CgkJbnIyZGFbaV0ubnIJID0gbnI7CgkJbnIyZGFbaV0uZGtlYWRkciA9IGRrZWFkZHI7CgoJCWtleXNbbnJdLmRrZWFkZHIgPSBka2VhZGRyOwoJCWtleXNbbnJdLngxID0gZGtlLngxOwoJCWtleXNbbnJdLngyID0gZGtlLngyOwoJCWtleXNbbnJdLngzID0gZGtlLngzOwoJCWtleXNbbnJdLnByZXZsdmw9IChzdHJ1Y3QgX3c5NWtleSopZGtlLnByZXZsdmw7CgkJa2V5c1tucl0ubmV4dHN1Yj0gKHN0cnVjdCBfdzk1a2V5Kilka2UubmV4dHN1YjsKCQlrZXlzW25yXS5uZXh0IAk9IChzdHJ1Y3QgX3c5NWtleSopZGtlLm5leHQ7Cgl9CglmcmVlKGRhdGEpOwoKCXFzb3J0KG5yMmRhLG5yb2Zka2VzLHNpemVvZihucjJkYVswXSksCiAgICAgICAgICAgICAgKGludCgqKShjb25zdCB2b2lkICosY29uc3Qgdm9pZCopKV93OTVka2Vjb21wKTsKCgkvKiBTVEVQIDI6IGtleWRhdGEgJiB2YWx1ZXMgKi8KCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGZkLCZoZmRpbmZvKSkKCQlyZXR1cm47CgllbmQgPSBoZmRpbmZvLm5GaWxlU2l6ZUxvdzsKCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZkaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLHJnZGJzZWN0aW9uLFNFRUtfU0VUKSkKCQlyZXR1cm47CglkYXRhID0gKGNoYXIqKXhtYWxsb2MoZW5kLXJnZGJzZWN0aW9uKTsKCWlmICgoZW5kLXJnZGJzZWN0aW9uKSE9X2xyZWFkMzIoaGZkLGRhdGEsZW5kLXJnZGJzZWN0aW9uKSkKCQlyZXR1cm47CglfbGNsb3NlMzIoaGZkKTsKCWN1cmRhdGEgPSBkYXRhOwoJbWVtY3B5KG1hZ2ljLGN1cmRhdGEsNCk7CgltZW1jcHkoJm9mZl9uZXh0X3JnZGIsY3VyZGF0YSs0LDQpOwoJbmV4dHJnZGIgPSBjdXJkYXRhK29mZl9uZXh0X3JnZGI7CglpZiAoc3RyY21wKG1hZ2ljLCJSR0RCIikpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsInRoaXJkIElGRiBoZWFkZXIgbm90IFJHREIsIGJ1dCAlc1xuIixtYWdpYyk7CgkJcmV0dXJuOwoJfQoJY3VyZGF0YT1kYXRhKzB4MjA7Cgl3aGlsZSAoMSkgewoJCXN0cnVjdAlka2ggZGtoOwoJCWludAlieXRlc3JlYWQ7CgkJc3RydWN0CV93OTVrZXkJKmtleSx4a2V5OwoKCQlieXRlc3JlYWQgPSAwOwoJCWlmIChjdXJkYXRhPj1uZXh0cmdkYikgewoJCQljdXJkYXRhID0gbmV4dHJnZGI7CgkJCWlmICghc3RybmNtcChjdXJkYXRhLCJSR0RCIiw0KSkgewoJCQkJbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCQkJCW5leHRyZ2RiID0gY3VyZGF0YStvZmZfbmV4dF9yZ2RiOwoJCQkJY3VyZGF0YSs9MHgyMDsKCQkJfSBlbHNlIHsKCQkJCWRwcmludGZfcmVnKHN0ZGRlYiwiYXQgZW5kIG9mIFJHREIgc2VjdGlvbiwgYnV0IG5vIG5leHQgaGVhZGVyICgleCBvZiAlbHgpLiBCcmVha2luZy5cbiIsY3VyZGF0YS1kYXRhLGVuZC1yZ2Ric2VjdGlvbik7CgkJCQlicmVhazsKCQkJfQoJCX0KI2RlZmluZSBYUkVBRCh3aGVyZXRvLGxlbikgXAoJaWYgKChjdXJkYXRhLWRhdGErbGVuKTxlbmQpIHtcCgkJbWVtY3B5KHdoZXJldG8sY3VyZGF0YSxsZW4pO1wKCQljdXJkYXRhKz1sZW47XAoJCWJ5dGVzcmVhZCs9bGVuO1wKCX0KCgkJWFJFQUQoJmRraCxzaXplb2YoZGtoKSk7CgkJbnIgPSBka2gubnJMUyArIChka2gubnJNUzw8OCk7CgkJaWYgKChucj5ucm9mZGtlcykgfHwgKGRraC5uckxTID09IDB4RkZGRikpIHsKCQkJaWYgKGRraC5uckxTID09IDB4RkZGRikgewoJCQkJLyogc2tpcCBvdmVyIGtleSB1c2luZyBuZXh0a2V5b2ZmICovCiAJCQkJY3VyZGF0YSs9ZGtoLm5leHRrZXlvZmYtc2l6ZW9mKHN0cnVjdCBka2gpOwoJCQkJY29udGludWU7CgkJCX0KCQkJZHByaW50Zl9yZWcoc3RkZGViLCJoYXZlbid0IGZvdW5kIG5yICVsZC5cbiIsbnIpOwoJCQlrZXkgPSAmeGtleTsKCQkJbWVtc2V0KGtleSwnXDAnLHNpemVvZih4a2V5KSk7CgkJfSBlbHNlIHsKCQkJa2V5ID0ga2V5cytucjsKCQkJaWYgKCFrZXktPmRrZWFkZHIpCgkJCQlkcHJpbnRmX3JlZyhzdGRkZWIsImtleSB3aXRoIG5yPSVsZCBoYXMgbm8gZGtlYWRkcj9cbiIsbnIpOwoJCX0KCQlrZXktPm5yb2Z2YWxzCT0gZGtoLnZhbHVlczsKCQlrZXktPm5hbWUJPSAoY2hhciopeG1hbGxvYyhka2gua2V5bmFtZWxlbisxKTsKCQlrZXktPnh4MQk9IGRraC54eDE7CgkJWFJFQUQoa2V5LT5uYW1lLGRraC5rZXluYW1lbGVuKTsKCQlrZXktPm5hbWVbZGtoLmtleW5hbWVsZW5dPTA7CgkJaWYgKGtleS0+bnJvZnZhbHMpIHsKCQkJa2V5LT52YWx1ZXMgPSAoc3RydWN0IF93OTVrZXl2YWx1ZSopeG1hbGxvYygKCQkJCXNpemVvZihzdHJ1Y3QgX3c5NWtleXZhbHVlKSprZXktPm5yb2Z2YWxzCgkJCSk7CgkJCWZvciAoaT0wO2k8a2V5LT5ucm9mdmFscztpKyspIHsKCQkJCXN0cnVjdAlka3YJZGt2OwoKCQkJCVhSRUFEKCZka3Ysc2l6ZW9mKGRrdikpOwoJCQkJa2V5LT52YWx1ZXNbaV0udHlwZSA9IGRrdi50eXBlOwoJCQkJa2V5LT52YWx1ZXNbaV0ubmFtZSA9IChjaGFyKil4bWFsbG9jKAoJCQkJCWRrdi52YWxuYW1lbGVuKzEKCQkJCSk7CgkJCQlrZXktPnZhbHVlc1tpXS5kYXRhbGVuID0gZGt2LnZhbGRhdGFsZW47CgkJCQlrZXktPnZhbHVlc1tpXS5kYXRhID0gKHVuc2lnbmVkIGNoYXIqKXhtYWxsb2MoCgkJCQkJZGt2LnZhbGRhdGFsZW4rMQoJCQkJKTsKCQkJCWtleS0+dmFsdWVzW2ldLngxICAgPSBka3YueDE7CgkJCQlYUkVBRChrZXktPnZhbHVlc1tpXS5uYW1lLGRrdi52YWxuYW1lbGVuKTsKCQkJCVhSRUFEKGtleS0+dmFsdWVzW2ldLmRhdGEsZGt2LnZhbGRhdGFsZW4pOwoJCQkJa2V5LT52YWx1ZXNbaV0uZGF0YVtka3YudmFsZGF0YWxlbl09MDsKCQkJCWtleS0+dmFsdWVzW2ldLm5hbWVbZGt2LnZhbG5hbWVsZW5dPTA7CgkJCQlrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQ9bGFzdG1vZGlmaWVkOwoJCQl9CgkJfQoJCWlmIChieXRlc3JlYWQgIT0gZGtoLm5leHRrZXlvZmYpIHsKCQkJaWYgKGRraC5ieXRlc3VzZWQgIT0gYnl0ZXNyZWFkKQoJCQkJZHByaW50Zl9yZWcoc3RkZGViLAoJCQkJCSJyZWFkIGhhcyBkaWZmZXJlbmNlIGluIHJlYWQgYnl0ZXMgKCVkKSBhbmQgbmV4dG9mZnNldCAoJWxkKSAoYnl0ZXN1c2VkPSVsZClcbiIsYnl0ZXNyZWFkLGRraC5uZXh0a2V5b2ZmLAoJCQkJCWRraC5ieXRlc3VzZWQKCQkJCSk7CgkJCWN1cmRhdGEgKz0gZGtoLm5leHRrZXlvZmYtYnl0ZXNyZWFkOwoJCX0KCQlrZXktPnByZXZsdmwJPSBfdzk1ZGtlbG9va3VwKChsb25nKWtleS0+cHJldmx2bCxucm9mZGtlcyxucjJkYSxrZXlzKTsKCQlrZXktPm5leHRzdWIJPSBfdzk1ZGtlbG9va3VwKChsb25nKWtleS0+bmV4dHN1Yixucm9mZGtlcyxucjJkYSxrZXlzKTsKCQlrZXktPm5leHQJPSBfdzk1ZGtlbG9va3VwKChsb25nKWtleS0+bmV4dCxucm9mZGtlcyxucjJkYSxrZXlzKTsKCQlpZiAoIWJ5dGVzcmVhZCkKCQkJYnJlYWs7Cgl9CglmcmVlKGRhdGEpOwoJX3c5NV93YWxrX3RyZWUobHBrZXksa2V5cyk7CglmcmVlKGtleXMpOwp9CgovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwoKLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWVkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJTFBLRVlTVFJVQ1QJbHBrZXksCgkJdGltZV90CQlsYXN0bW9kaWZpZWQsCgkJaW50CQlsZXZlbAopIHsKCXN0cnVjdCBfdzMxX2RpcmVudAkqZGlyOwoJc3RydWN0IF93MzFfa2V5ZW50CSprZXk7CglzdHJ1Y3QgX3czMV92YWxlbnQJKnZhbDsKCUxQS0VZU1RSVUNUCQl4bHBrZXkgPSBOVUxMOwoJTFBXU1RSCQkJbmFtZSx2YWx1ZTsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcDMyQSh0YWlsLCIuY2xhc3NlcyIpKSB7CgkJCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQoJCQluYW1lPVNUUklORzMyX0R1cEFuc2lUb1VuaSh0YWlsKTsKCgkJCXhscGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CgkJCQkJdmFsdWU9U1RSSU5HMzJfRHVwQW5zaVRvVW5pKHRhaWwpOwoJCQkJCV9maW5kX29yX2FkZF92YWx1ZSh4bHBrZXksTlVMTCxSRUdfU1osKExQQllURSl2YWx1ZSxsc3RybGVuMzJXKHZhbHVlKSoyKzIsbGFzdG1vZGlmaWVkKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiX193MzFfZHVtcHRyZWU6c3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHhscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9Cn0KCnZvaWQKX3czMV9sb2FkcmVnKCkgewoJSEZJTEUzMgkJCWhmOwoJc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CglzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKCXVuc2lnbmVkIGNoYXIJCSp0eHQ7CglpbnQJCQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoJSEtFWQkJCWhrZXk7CglMUEtFWVNUUlVDVAkJbHBrZXk7CgoJaGYgPSBPcGVuRmlsZTMyKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZDMyKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIl93MzFfbG9hZHJlZzpyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIl93MzFfbG9hZHJlZzpyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKCS8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KCXRhYiA9IHhtYWxsb2MobGVuKTsKCWlmIChsZW4hPV9scmVhZDMyKGhmLHRhYixsZW4pKSB7CgkJZHByaW50Zl9yZWcoc3RkZXJyLCJfdzMxX2xvYWRyZWc6Y291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCgkJZnJlZSh0YWIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlazMyKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlkcHJpbnRmX3JlZyhzdGRlcnIsIl93MzFfbG9hZHJlZzpjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZDMyKGhmLHR4dCxoZWFkLnRleHRzaXplKSkgewoJCWRwcmludGZfcmVnKHN0ZGVyciwiX3czMV9sb2FkcmVnOnRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlkcHJpbnRmX3JlZyhzdGRlcnIsIl93MzFfbG9hZHJlZzpHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiXFxTT0ZUV0FSRVxcQ2xhc3NlcyIsJmhrZXkpIT1FUlJPUl9TVUNDRVNTKQoJCXJldHVybjsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglfX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsMCk7CglmcmVlKHRhYik7CglmcmVlKHR4dCk7CglfbGNsb3NlMzIoaGYpOwoJcmV0dXJuOwp9Cgp2b2lkClNIRUxMX0xvYWRSZWdpc3RyeSgpIHsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoKCglpZiAoa2V5X2NsYXNzZXNfcm9vdD09TlVMTCkKCQlTSEVMTF9Jbml0KCk7CgoJLyogTG9hZCB3aW5kb3dzIDMuMSBlbnRyaWVzICovCglfdzMxX2xvYWRyZWcoKTsKCS8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCglfdzk1X2xvYWRyZWcoIkM6XFxzeXN0ZW0uMXN0IiwJa2V5X2xvY2FsX21hY2hpbmUpOwoJX3c5NV9sb2FkcmVnKCJzeXN0ZW0uZGF0IiwJa2V5X2xvY2FsX21hY2hpbmUpOwoJX3c5NV9sb2FkcmVnKCJ1c2VyLmRhdCIsCWtleV91c2Vycyk7CgoJLyogdGhlIGdsb2JhbCB1c2VyIGRlZmF1bHQgaXMgbG9hZGVkIHVuZGVyIEhLRVlfVVNFUlNcXC5EZWZhdWx0ICovCglSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCV93aW5lX2xvYWRyZWcobHBrZXksU0FWRV9VU0VSU19ERUZBVUxULDApOwoKCS8qIEhLRVlfVVNFUlNcXC5EZWZhdWx0IGlzIGNvcGllZCB0byBIS0VZX0NVUlJFTlRfVVNFUiAqLwoJX2NvcHlfcmVnaXN0cnkobHBrZXksa2V5X2N1cnJlbnRfdXNlcik7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgKi8KCV93aW5lX2xvYWRyZWcoa2V5X2xvY2FsX21hY2hpbmUsU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsMCk7CgoJLyogbG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzICovCgoJLyogRklYTUU6IHVzZSBnZXRlbnYoIkhPTUUiKSBvciBnZXRwd3VpZChnZXR1aWQoKSktPnB3X2RpciA/PyAqLwoKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKSB7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJX3dpbmVfbG9hZHJlZyhrZXlfY3VycmVudF91c2VyLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQlfd2luZV9sb2FkcmVnKGtleV9sb2NhbF9tYWNoaW5lLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7Cgl9IGVsc2UKCQlmcHJpbnRmKHN0ZGVyciwiU0hFTExfTG9hZFJlZ2lzdHJ5OmZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSB7CgkJRFdPUkQJanVuayx0eXBlLGxlbjsKCQljaGFyCWRhdGFbNV07CgoJCWxlbj00OwoJCWlmICgoCVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJZGF0YSwKCQkJCSZsZW4KCQkJKSE9RVJST1JfU1VDQ0VTUykgfHwKCQkJdHlwZSAhPSBSRUdfU1oKCQkpCgkJCVJlZ1NldFZhbHVlRXgzMkEoaGtleSxWQUxfU0FWRVVQREFURUQsMCxSRUdfU1osInllcyIsNCk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBGSVhNRTogc2VjdXJpdHksb3B0aW9ucyxkZXNpcmVkYWNjZXNzLC4uLgogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgovKiBSZWdPcGVuS2V5RXhXCQlbQURWQVBJMzIuMTUwXSAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUV4MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdSZXNlcnZlZCwKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBIS0VZCXJldGtleQopIHsKCUxQS0VZU1RSVUNUCWxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5RXgzMlcoJWx4LCVzLCVsZCwlbHgsJXApXG4iLAoJCShMT05HKWhrZXksVzJDKGxwc3pTdWJLZXksMCksZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleQoJKTsKCglscE5leHRLZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBOZXh0S2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CgkJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoJCSpyZXRrZXk9Y3VycmVudGhhbmRsZTsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHB4a2V5LHNhbURlc2lyZWQpOwoJKnJldGtleQk9IGN1cnJlbnRoYW5kbGU7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuCVNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ09wZW5LZXlXCQkJW0FEVkFQSTMyLjE1MV0gKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkzMlcoCglIS0VZCWhrZXksCglMUENXU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5MzJXKCVseCwlcywlcClcbiIsCgkJKExPTkcpaGtleSxXMkMobHBzelN1YktleSwwKSxyZXRrZXkKCSk7CglyZXR1cm4gUmVnT3BlbktleUV4MzJXKGhrZXksbHBzelN1YktleSwwLEtFWV9BTExfQUNDRVNTLHJldGtleSk7Cn0KCgovKiBSZWdPcGVuS2V5RXhBCQlbQURWQVBJMzIuMTQ5XSAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUV4MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1Jlc2VydmVkLAoJUkVHU0FNCXNhbURlc2lyZWQsCglMUEhLRVkJcmV0a2V5CikgewoJTFBXU1RSCWxwc3pTdWJLZXlXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnT3BlbktleUV4MzJBKCVseCwlcywlbGQsJWx4LCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXksZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleQoJKTsKCWlmIChscHN6U3ViS2V5KQoJCWxwc3pTdWJLZXlXPXN0cmR1cEEyVyhscHN6U3ViS2V5KTsKCWVsc2UKCQlscHN6U3ViS2V5Vz1OVUxMOwoJcmV0PVJlZ09wZW5LZXlFeDMyVyhoa2V5LGxwc3pTdWJLZXlXLGR3UmVzZXJ2ZWQsc2FtRGVzaXJlZCxyZXRrZXkpOwoJaWYgKGxwc3pTdWJLZXlXKQoJCWZyZWUobHBzelN1YktleVcpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnT3BlbktleUEJCQlbQURWQVBJMzIuMTQ4XSAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTMyQSgKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnT3BlbktleTMyQSglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxyZXRrZXkKCSk7CglyZXR1cm4JUmVnT3BlbktleUV4MzJBKGhrZXksbHBzelN1YktleSwwLEtFWV9BTExfQUNDRVNTLHJldGtleSk7Cn0KCi8qIFJlZ09wZW5LZXkJCQlbU0hFTEwuMV0gW0tFUk5FTC4yMTddICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCUxQSEtFWQlyZXRrZXkKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ09wZW5LZXkxNiglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxyZXRrZXkKCSk7CglyZXR1cm4gUmVnT3BlbktleTMyQShoa2V5LGxwc3pTdWJLZXkscmV0a2V5KTsKfQoKLyogCiAqIENyZWF0ZSBrZXlzCiAqIAogKiBBbGwgdGhvc2UgZnVuY3Rpb25zIGNvbnZlcnQgdGhlaXIgcmVzcGVjdGl2ZSAKICogYXJndW1lbnRzIGFuZCBjYWxsIFJlZ0NyZWF0ZUtleUV4VyBhdCB0aGUgZW5kLgogKgogKiBGSVhNRTogbm8gc2VjdXJpdHksbm8gYWNjZXNzIGF0dHJpYixubyBvcHRpb25oYW5kbGluZyB5ZXQuCiAqCiAqIENhbGxwYXRoOgogKiBSZWdDcmVhdGVLZXkxNiAtPiBSZWdDcmVhdGVLZXkzMkEgLT4gUmVnQ3JlYXRlS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnQ3JlYXRlS2V5MzJXICAgLT4gUmVnQ3JlYXRlS2V5RXgzMlcKICovCgovKiBSZWdDcmVhdGVLZXlFeFcJCVtBRFZBUEkzMi4xMzFdICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeDMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCURXT1JECWR3UmVzZXJ2ZWQsCglMUFdTVFIJbHBzekNsYXNzLAoJRFdPUkQJZmR3T3B0aW9ucywKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywKCUxQSEtFWQlyZXRrZXksCglMUERXT1JECWxwRGlzcG9zCikgewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKLypGSVhNRTogaGFuZGxlIHNlY3VyaXR5L2FjY2Vzcy93aGF0ZXZlciAqLwoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDcmVhdGVLZXlFeDMyVyglbHgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLAoJCShMT05HKWhrZXksCgkJVzJDKGxwc3pTdWJLZXksMCksCgkJZHdSZXNlcnZlZCwKCQlXMkMobHBzekNsYXNzLDEpLAoJCWZkd09wdGlvbnMsCgkJc2FtRGVzaXJlZCwKCQlscFNlY0F0dHJpYnMsCgkJcmV0a2V5LAoJCWxwRGlzcG9zCgkpOwoKCWxwTmV4dEtleQk9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscE5leHRLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKCQlhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwoJCWxwTmV4dEtleS0+ZmxhZ3N8PVJFR19PUFRJT05fVEFJTlRFRDsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkKCQkJYnJlYWs7CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWlmIChscHhrZXkpIHsKCQlhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CgkJbHB4a2V5LT5mbGFncyAgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKCQlpZiAobHBEaXNwb3MpCgkJCSpscERpc3Bvcwk9IFJFR19PUEVORURfRVhJU1RJTkdfS0VZOwoJCUZSRUVfS0VZX1BBVEg7CgkJcmV0dXJuCVNIRUxMX0VSUk9SX1NVQ0NFU1M7Cgl9CgkvKiBnb29kLiBub3cgdGhlIGhhcmQgcGFydCAqLwoJd2hpbGUgKHdwc1tpXSkgewoJCWxwbHBQcmV2S2V5CT0gJihscE5leHRLZXktPm5leHRzdWIpOwoJCWxweGtleQkJPSAqbHBscFByZXZLZXk7CgkJd2hpbGUgKGxweGtleSkgewoJCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl9CgkJKmxwbHBQcmV2S2V5PW1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJaWYgKCEqbHBscFByZXZLZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKCQkJcmV0dXJuIFNIRUxMX0VSUk9SX09VVE9GTUVNT1JZOwoJCX0KCQltZW1zZXQoKmxwbHBQcmV2S2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCSgqbHBscFByZXZLZXkpLT5rZXluYW1lCT0gc3RyZHVwVyh3cHNbaV0pOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0CT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dHN1Ygk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPnZhbHVlcwk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5yb2Z2YWx1ZXMgPSAwOwoJCSgqbHBscFByZXZLZXkpLT5mbGFncyAJPSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJaWYgKGxwc3pDbGFzcykKCQkJKCpscGxwUHJldktleSktPmNsYXNzID0gc3RyZHVwVyhscHN6Q2xhc3MpOwoJCWVsc2UKCQkJKCpscGxwUHJldktleSktPmNsYXNzID0gTlVMTDsKCQlscE5leHRLZXkJPSAqbHBscFByZXZLZXk7CgkJaSsrOwoJfQoJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoKCS8qRklYTUU6IGZsYWcgaGFuZGxpbmcgY29ycmVjdD8gKi8KCWxwTmV4dEtleS0+ZmxhZ3M9IGZkd09wdGlvbnMgfFJFR19PUFRJT05fVEFJTlRFRDsKCWlmIChscHN6Q2xhc3MpCgkJbHBOZXh0S2V5LT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCWVsc2UKCQlscE5leHRLZXktPmNsYXNzID0gTlVMTDsKCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKCWlmIChscERpc3BvcykKCQkqbHBEaXNwb3MJPSBSRUdfQ1JFQVRFRF9ORVdfS0VZOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdDcmVhdGVLZXlXCQlbQURWQVBJMzIuMTMyXSAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCURXT1JECWp1bmsscmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5MzJXKCVseCwlcywlcClcbiIsCgkJKExPTkcpaGtleSxXMkMobHBzelN1YktleSwwKSxyZXRrZXkKCSk7CglyZXQ9UmVnQ3JlYXRlS2V5RXgzMlcoCgkJaGtleSwJCS8qIGtleSBoYW5kbGUgKi8KCQlscHN6U3ViS2V5LAkvKiBzdWJrZXkgbmFtZSAqLwoJCTAsCQkvKiByZXNlcnZlZCA9IDAgKi8KCQlOVUxMLAkJLyogbHBzekNsYXNzPyBGSVhNRTogPyAqLwoJCVJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLAkvKiBvcHRpb25zICovCgkJS0VZX0FMTF9BQ0NFU1MsCS8qIGRlc2lyZWQgYWNjZXNzIGF0dHJpYnMgKi8KCQlOVUxMLAkJLyogbHBzZWN1cml0eSBhdHRyaWJ1dGVzICovCgkJcmV0a2V5LAkJLyogbHByZXRrZXkgKi8KCQkmanVuawkJLyogZGlzcG9zaXRpb24gdmFsdWUgKi8KCSk7CglyZXR1cm4JcmV0Owp9CgovKiBSZWdDcmVhdGVLZXlFeEEJCVtBRFZBUEkzMi4xMzBdICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeDMyQSgKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdSZXNlcnZlZCwKCUxQU1RSCWxwc3pDbGFzcywKCURXT1JECWZkd09wdGlvbnMsCglSRUdTQU0Jc2FtRGVzaXJlZCwKCUxQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsCglMUEhLRVkJcmV0a2V5LAoJTFBEV09SRAlscERpc3BvcwopIHsKCUxQV1NUUglscHN6U3ViS2V5VyxscHN6Q2xhc3NXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5RXgzMkEoJWx4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIiwKCQkoTE9ORyloa2V5LAoJCWxwc3pTdWJLZXksCgkJZHdSZXNlcnZlZCwKCQlscHN6Q2xhc3MsCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleSkKCQlscHN6U3ViS2V5Vz1zdHJkdXBBMlcobHBzelN1YktleSk7CgllbHNlCgkJbHBzelN1YktleVc9TlVMTDsKCWlmIChscHN6Q2xhc3MpCgkJbHBzekNsYXNzVz1zdHJkdXBBMlcobHBzekNsYXNzKTsKCWVsc2UKCQlscHN6Q2xhc3NXPU5VTEw7CglyZXQ9UmVnQ3JlYXRlS2V5RXgzMlcoCgkJaGtleSwKCQlscHN6U3ViS2V5VywKCQlkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleVcpCgkJZnJlZShscHN6U3ViS2V5Vyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnQ3JlYXRlS2V5QQkJW0FEVkFQSTMyLjEyOV0gKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTMyQSgKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCURXT1JECWp1bms7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDcmVhdGVLZXkzMkEoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuCVJlZ0NyZWF0ZUtleUV4MzJBKAoJCWhrZXksCQkvKiBrZXkgaGFuZGxlICovCgkJbHBzelN1YktleSwJLyogc3Via2V5IG5hbWUgKi8KCQkwLAkJLyogcmVzZXJ2ZWQgPSAwICovCgkJTlVMTCwJCS8qIGxwc3pDbGFzcz8gRklYTUU6ID8gKi8KCQlSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwvKiBvcHRpb25zICovCgkJS0VZX0FMTF9BQ0NFU1MsCS8qIGRlc2lyZWQgYWNjZXNzIGF0dHJpYnMgKi8KCQlOVUxMLAkJLyogbHBzZWN1cml0eSBhdHRyaWJ1dGVzICovCgkJcmV0a2V5LAkJLyogbHByZXRrZXkgKi8KCQkmanVuawkJLyogZGlzcG9zaXRpb24gdmFsdWUgKi8KCSk7Cn0KCi8qIFJlZ0NyZWF0ZUtleQkJCVtTSEVMTC4yXSBbS0VSTkVMLjIxOF0gKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDcmVhdGVLZXkxNiglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxyZXRrZXkKCSk7CglyZXR1cm4gUmVnQ3JlYXRlS2V5MzJBKGhrZXksbHBzelN1YktleSxyZXRrZXkpOwp9CgovKiAKICogUXVlcnkgVmFsdWUgRnVuY3Rpb25zCiAqIFdpbjMyIGRpZmZlcnMgYmV0d2VlbiBrZXluYW1lcyBhbmQgdmFsdWVuYW1lcy4gCiAqIG11bHRpcGxlIHZhbHVlcyBtYXkgYmVsb25nIHRvIG9uZSBrZXksIHRoZSBzcGVjaWFsIHZhbHVlCiAqIHdpdGggbmFtZSBOVUxMIGlzIHRoZSBkZWZhdWx0IHZhbHVlIHVzZWQgYnkgdGhlIHdpbjMxCiAqIGNvbXBhdCBmdW5jdGlvbnMuCiAqCiAqIENhbGxwYXRoOgogKiBSZWdRdWVyeVZhbHVlMTYgLT4gUmVnUXVlcnlWYWx1ZTMyQSAtPiBSZWdRdWVyeVZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUzMlcgLT4gUmVnUXVlcnlWYWx1ZUV4MzJXCiAqLwoKLyogUmVnUXVlcnlWYWx1ZUV4VwkJW0FEVkFQSTMyLjE1OF0gKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDMyVygKCUhLRVkJaGtleSwKCUxQV1NUUglscHN6VmFsdWVOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlRXgzMlcoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwKCQloa2V5LFcyQyhscHN6VmFsdWVOYW1lLDApLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoKCWxwa2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwc3pWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKQoJCQkpCgkJCQlicmVhazsKCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CgkJCWlmIChscGJEYXRhKSB7CgkJCQkqKFdDSEFSKilscGJEYXRhID0gMDsKCQkJCSpscGNiRGF0YQk9IDI7CgkJCX0KCQkJaWYgKGxwZHdUeXBlKQoJCQkJKmxwZHdUeXBlCT0gUkVHX1NaOwoJCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCQl9CgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsvKkZJWE1FOiBjb3JyZWN0IHJldHVybj8gKi8KCX0KCWlmIChscGR3VHlwZSkKCQkqbHBkd1R5cGUJPSBscGtleS0+dmFsdWVzW2ldLnR5cGU7CglpZiAobHBiRGF0YT09TlVMTCkgewoJCWlmIChscGNiRGF0YT09TlVMTCkKCQkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7CgkJKmxwY2JEYXRhCT0gbHBrZXktPnZhbHVlc1tpXS5sZW47CgkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cgl9CglpZiAoKmxwY2JEYXRhPGxwa2V5LT52YWx1ZXNbaV0ubGVuKSB7CgkJKihXQ0hBUiopbHBiRGF0YQoJCQk9IDA7CgkJKmxwY2JEYXRhCT0gbHBrZXktPnZhbHVlc1tpXS5sZW47CgkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCX0KCW1lbWNweShscGJEYXRhLGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGtleS0+dmFsdWVzW2ldLmxlbik7CgkqbHBjYkRhdGEJPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdRdWVyeVZhbHVlVwkJW0FEVkFQSTMyLjE1OV0gKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUzMlcoCglIS0VZCWhrZXksCglMUFdTVFIJbHBzelN1YktleSwKCUxQV1NUUglscHN6RGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0LGxwZHdUeXBlOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlWYWx1ZTMyVygleCwlcywlcCwlbGQpXG4tPiIsCgkJaGtleSxXMkMobHBzelN1YktleSwwKSxscHN6RGF0YSwKCQlscGNiRGF0YT8qbHBjYkRhdGE6MAoJKTsKCgkvKiBvbmx5IG9wZW4gc3Via2V5LCBpZiB3ZSByZWFsbHkgZG8gZGVzY2VuZCAqLwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQJPSBSZWdPcGVuS2V5MzJXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleQk9IGhrZXk7CgoJbHBkd1R5cGUJPSBSRUdfU1o7CglyZXQJPSBSZWdRdWVyeVZhbHVlRXgzMlcoCgkJeGhrZXksCgkJTlVMTCwJCS8qIHZhcm5hbWUgTlVMTCAtPiBjb21wYXQgKi8KCQlOVUxMLAkJLyogbHBkd1Jlc2VydmVkLCBtdXN0IGJlIE5VTEwgKi8KCQkmbHBkd1R5cGUsCgkJKExQQllURSlscHN6RGF0YSwKCQlscGNiRGF0YQoJKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdRdWVyeVZhbHVlRXhBCQlbQURWQVBJMzIuMTU3XSAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCUxQQllURQlidWY7CglEV09SRAlyZXQsbXl4bGVuOwoJRFdPUkQJKm15bGVuOwoJRFdPUkQJdHlwZTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWVFeDMyQSgleCwlcywlcCwlcCwlcCwlbGQpXG4tPiIsCgkJaGtleSxscHN6VmFsdWVOYW1lLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJbHBzelZhbHVlTmFtZVc9c3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOwoJZWxzZSAKCQlscHN6VmFsdWVOYW1lVz1OVUxMOwoKCWlmIChscGR3VHlwZSkKCQl0eXBlPSpscGR3VHlwZTsKCglpZiAobHBiRGF0YSkgewoJCW15eGxlbiAgPSAwOwoJCW15bGVuCT0gJm15eGxlbjsKCQlidWYJPSB4bWFsbG9jKDQpOwoJCXJldD1SZWdRdWVyeVZhbHVlRXgzMlcoCgkJCWhrZXksCgkJCWxwc3pWYWx1ZU5hbWVXLAoJCQlscGR3UmVzZXJ2ZWQsCgkJCSZ0eXBlLAoJCQlidWYsCgkJCW15bGVuCgkJKTsKCQlmcmVlKGJ1Zik7CgkJaWYgKHJldD09RVJST1JfTU9SRV9EQVRBKSB7CgkJCWJ1Zgk9IChMUEJZVEUpeG1hbGxvYygqbXlsZW4pOwoJCX0gZWxzZSB7CgkJCWJ1Zgk9IChMUEJZVEUpeG1hbGxvYygyKigqbHBjYkRhdGEpKTsKCQkJbXl4bGVuICA9IDIqKCpscGNiRGF0YSk7CgkJfQoJfSBlbHNlIHsKCQlidWY9TlVMTDsKCQlpZiAobHBjYkRhdGEpIHsKCQkJbXl4bGVuCT0gKmxwY2JEYXRhKjI7CgkJCW15bGVuCT0gJm15eGxlbjsKCQl9IGVsc2UKCQkJbXlsZW4JPSBOVUxMOwoJfQoJcmV0PVJlZ1F1ZXJ5VmFsdWVFeDMyVygKCQloa2V5LAoJCWxwc3pWYWx1ZU5hbWVXLAoJCWxwZHdSZXNlcnZlZCwKCQkmdHlwZSwKCQlidWYsCgkJbXlsZW4KCSk7CglpZiAobHBkd1R5cGUpIAoJCSpscGR3VHlwZT10eXBlOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWlmIChidWYpIHsKCQkJaWYgKFVOSUNPTlZNQVNLICYgKDE8PCh0eXBlKSkpIHsKCQkJCS8qIGNvbnZlcnQgVU5JQ09ERSB0byBBU0NJSSAqLwoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWJ1Zik7CgkJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCQkJfSBlbHNlIHsKCQkJCWlmIChteXhsZW4+KmxwY2JEYXRhKQoJCQkJCXJldAk9IEVSUk9SX01PUkVfREFUQTsKCQkJCWVsc2UKCQkJCQltZW1jcHkobHBiRGF0YSxidWYsbXl4bGVuKTsKCgkJCQkqbHBjYkRhdGEJPSBteXhsZW47CgkJCX0KCQl9IGVsc2UgewoJCQlpZiAoKFVOSUNPTlZNQVNLICYgKDE8PCh0eXBlKSkpICYmIGxwY2JEYXRhKQoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7CgkJfQoJfSBlbHNlIHsKCQlpZiAoKFVOSUNPTlZNQVNLICYgKDE8PCh0eXBlKSkpICYmIGxwY2JEYXRhKQoJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCX0KCWlmIChidWYpCgkJZnJlZShidWYpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnUXVlcnlWYWx1ZUV4CQlbS0VSTkVMLjIyNV0gKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlWYWx1ZUV4MTYoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwKCQloa2V5LGxwc3pWYWx1ZU5hbWUsbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsCgkJbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCWhrZXksCgkJbHBzelZhbHVlTmFtZSwKCQlscGR3UmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YSwKCQlscGNiRGF0YQoJKTsKfQoKLyogUmVnUXVlcnlWYWx1ZUEJCVtBRFZBUEkzMi4xNTZdICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelN1YktleSwKCUxQU1RSCWxwc3pEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeVZhbHVlMzJBKCV4LCVzLCVwLCVsZClcbiIsCgkJaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLAoJCWxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoKCS8qIG9ubHkgb3BlbiBzdWJrZXksIGlmIHdlIHJlYWxseSBkbyBkZXNjZW5kICovCglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldAk9IFJlZ09wZW5LZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXkJPSBoa2V5OwoKCWxwZHdUeXBlCT0gUkVHX1NaOwoJcmV0CT0gUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCXhoa2V5LAoJCU5VTEwsCQkvKiBscHN6VmFsdWVOYW1lIE5VTEwgLT4gY29tcGF0ICovCgkJTlVMTCwJCS8qIGxwZHdSZXNlcnZlZCwgbXVzdCBiZSBOVUxMICovCgkJJmxwZHdUeXBlLAoJCShMUEJZVEUpbHBzekRhdGEsCgkJbHBjYkRhdGEKCSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnUXVlcnlWYWx1ZQkJW1NIRUxMLjZdIFtLRVJORUwuMjI0XSAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelN1YktleSwKCUxQU1RSCWxwc3pEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlWYWx1ZTE2KCV4LCVzLCVwLCVsZClcbiIsCgkJaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowCgkpOwoJLyogSEFDSzogdGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MKCSAqICAgICAgIGFueXdheSwgc28gd2UganVzdCBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuCgkgKiAgICAgICAodGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseTspIGhvcGVmdWxseSBmaXhlcyBBbGR1cyBGSDQpCgkgKi8KCWlmIChscGNiRGF0YSkKCQkqbHBjYkRhdGEgJj0gMHhGRkZGOwoJcmV0dXJuIFJlZ1F1ZXJ5VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhKTsKfQoKLyoKICogU2V0dGluZyB2YWx1ZXMgb2YgUmVnaXN0cnkga2V5cwogKgogKiBDYWxscGF0aDoKICogUmVnU2V0VmFsdWUxNiAtPiBSZWdTZXRWYWx1ZTMyQSAtPiBSZWdTZXRWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZTMyVyAgIC0+IFJlZ1NldFZhbHVlRXgzMlcKICovCgovKiBSZWdTZXRWYWx1ZUV4VwkJW0FEVkFQSTMyLjE3MF0gKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgzMlcoCglIS0VZCWhrZXksCglMUFdTVFIJbHBzelZhbHVlTmFtZSwKCURXT1JECWR3UmVzZXJ2ZWQsCglEV09SRAlkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCURXT1JECWNiRGF0YQopIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJaW50CQlpOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVFeDMyVygleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsCgkJaGtleSxXMkMobHBzelZhbHVlTmFtZSwwKSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YQoJKTsKCS8qIHdlIG5vIGxvbmdlciBjYXJlIGFib3V0IHRoZSBscGJEYXRhIHR5cGUgaGVyZS4uLiAqLwoJbHBrZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCglscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoKCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkJKGxwa2V5LT5ucm9mdmFsdWVzKzEpKnNpemVvZihLRVlWQUxVRSkKCQkJCSk7CgkJbHBrZXktPm5yb2Z2YWx1ZXMrKzsKCQltZW1zZXQobHBrZXktPnZhbHVlcytpLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7Cgl9CglpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCWlmIChscHN6VmFsdWVOYW1lKQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBzdHJkdXBXKGxwc3pWYWx1ZU5hbWUpOwoJCWVsc2UKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gTlVMTDsKCWxwa2V5LT52YWx1ZXNbaV0ubGVuCT0gY2JEYXRhOwoJbHBrZXktPnZhbHVlc1tpXS50eXBlCT0gZHdUeXBlOwoJaWYgKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSAhPU5VTEwpCgkJZnJlZShscGtleS0+dmFsdWVzW2ldLmRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5kYXRhCT0gKExQQllURSl4bWFsbG9jKGNiRGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmxhc3Rtb2RpZmllZCA9IHRpbWUoTlVMTCk7CgltZW1jcHkobHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwYkRhdGEsY2JEYXRhKTsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdTZXRWYWx1ZUV4QQkJW0FEVkFQSTMyLjE2OV0gKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgzMkEoCglIS0VZCWhrZXksCglMUFNUUglscHN6VmFsdWVOYW1lLAoJRFdPUkQJZHdSZXNlcnZlZCwKCURXT1JECWR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJRFdPUkQJY2JEYXRhCikgewoJTFBCWVRFCWJ1ZjsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCURXT1JECXJldDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlRXgzMkEoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4tPiIsCgkJaGtleSxscHN6VmFsdWVOYW1lLGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhCgkpOwoJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIHsKCQlidWY9KExQQllURSlzdHJkdXBBMlcobHBiRGF0YSk7CgkJY2JEYXRhPTIqc3RybGVuKGxwYkRhdGEpKzI7Cgl9IGVsc2UKCQlidWY9bHBiRGF0YTsKCWlmIChscHN6VmFsdWVOYW1lKQoJCWxwc3pWYWx1ZU5hbWVXID0gc3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOwoJZWxzZQoJCWxwc3pWYWx1ZU5hbWVXID0gTlVMTDsKCXJldD1SZWdTZXRWYWx1ZUV4MzJXKGhrZXksbHBzelZhbHVlTmFtZVcsZHdSZXNlcnZlZCxkd1R5cGUsYnVmLGNiRGF0YSk7CglpZiAobHBzelZhbHVlTmFtZVcpCgkJZnJlZShscHN6VmFsdWVOYW1lVyk7CglpZiAoYnVmIT1scGJEYXRhKQoJCWZyZWUoYnVmKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ1NldFZhbHVlRXgJCVtLRVJORUwuMjI2XSAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCURXT1JECWR3UmVzZXJ2ZWQsCglEV09SRAlkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCURXT1JECWNiRGF0YQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVFeDE2KCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuLT4iLAoJCWhrZXksbHBzelZhbHVlTmFtZSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YQoJKTsKCXJldHVybiBSZWdTZXRWYWx1ZUV4MzJBKGhrZXksbHBzelZhbHVlTmFtZSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7Cn0KCi8qIFJlZ1NldFZhbHVlVwkJCVtBRFZBUEkzMi4xNzFdICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTMyVygKCUhLRVkJaGtleSwKCUxQQ1dTVFIJbHBzelN1YktleSwKCURXT1JECWR3VHlwZSwKCUxQQ1dTVFIJbHBzekRhdGEsCglEV09SRAljYkRhdGEKKSB7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWUzMlcoJXgsJXMsJWxkLCVzLCVsZClcbi0+IiwKCQloa2V5LFcyQyhscHN6U3ViS2V5LDApLGR3VHlwZSxXMkMobHBzekRhdGEsMCksY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MzJXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJZnByaW50ZihzdGRkZWIsIlJlZ1NldFZhbHVlWCBjYWxsZWQgd2l0aCBkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzIpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlWCBjYWxsZWQgd2l0aCBsZW49JWxkICE9IHN0cmxlbiglcykrMT0lZCFcbiIsCgkJCWNiRGF0YSxXMkMobHBzekRhdGEsMCksMipsc3RybGVuMzJXKGxwc3pEYXRhKSsyCgkJKTsKCQljYkRhdGE9Mipsc3RybGVuMzJXKGxwc3pEYXRhKSsyOwoJfQoJcmV0PVJlZ1NldFZhbHVlRXgzMlcoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoaGtleSE9eGhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKCn0KLyogUmVnU2V0VmFsdWVBCQkJW0FEVkFQSTMyLjE2OF0gKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1R5cGUsCglMUENTVFIJbHBzekRhdGEsCglEV09SRAljYkRhdGEKKSB7CglEV09SRAlyZXQ7CglIS0VZCXhoa2V5OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWUzMkEoJXgsJXMsJWxkLCVzLCVsZClcbi0+IiwKCQloa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YQoJKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleTE2KGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVBIGNhbGxlZCB3aXRoIGR3VHlwZT0lbGQhXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPXN0cmxlbihscHN6RGF0YSkrMSkKCQljYkRhdGE9c3RybGVuKGxwc3pEYXRhKSsxOwoJcmV0PVJlZ1NldFZhbHVlRXgzMkEoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnU2V0VmFsdWUJCQlbS0VSTkVMLjIyMV0gW1NIRUxMLjVdICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1R5cGUsCglMUENTVFIJbHBzekRhdGEsCglEV09SRAljYkRhdGEKKSB7CglEV09SRAlyZXQ7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlMTYoJXgsJXMsJWxkLCVzLCVsZClcbi0+IiwKCQloa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YQoJKTsKCXJldD1SZWdTZXRWYWx1ZTMyQShoa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YSk7CglyZXR1cm4gcmV0Owp9CgovKiAKICogS2V5IEVudW1lcmF0aW9uCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtS2V5MTYgLT4gUmVnRW51bUtleTMyQSAtPiBSZWdFbnVtS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0VudW1LZXkzMlcgICAtPiBSZWdFbnVtS2V5RXgzMlcKICovCgovKiBSZWdFbnVtS2V5RXhXCQlbQURWQVBJMzIuMTM5XSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJXKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQV1NUUglscHN6TmFtZSwKCUxQRFdPUkQJbHBjY2hOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUFdTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJRklMRVRJTUUJKmZ0CikgewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bUtleUV4MzJXKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSwqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdAoJKTsKCWxwa2V5PWxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKCFscGtleS0+bmV4dHN1YikKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWxweGtleT1scGtleS0+bmV4dHN1YjsKCXdoaWxlIChpU3Via2V5ICYmIGxweGtleSkgewoJCWlTdWJrZXktLTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJaWYgKGlTdWJrZXkgfHwgIWxweGtleSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWlmICgyKmxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKSsyPipscGNjaE5hbWUpCgkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCW1lbWNweShscHN6TmFtZSxscHhrZXktPmtleW5hbWUsbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKjIrMik7CglpZiAobHBzekNsYXNzKSB7CgkJLyogd2hhdCBzaG91bGQgd2Ugd3JpdGUgaW50byBpdD8gKi8KCQkqbHBzekNsYXNzCQk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgp9CgovKiBSZWdFbnVtS2V5VwkJCVtBRFZBUEkzMi4xNDBdICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJXKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQV1NUUglscHN6TmFtZSwKCURXT1JECWxwY2NoTmFtZQopIHsKCUZJTEVUSU1FCWZ0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bUtleTMyVygleCwlbGQsJXAsJWxkKVxuLT4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUKCSk7CglyZXR1cm4gUmVnRW51bUtleUV4MzJXKGhrZXksaVN1YmtleSxscHN6TmFtZSwmbHBjY2hOYW1lLE5VTEwsTlVMTCxOVUxMLCZmdCk7Cn0KLyogUmVnRW51bUtleUV4QQkJW0FEVkFQSTMyLjEzOF0gKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeDMyQSgKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFNUUglscHN6TmFtZSwKCUxQRFdPUkQJbHBjY2hOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUFNUUglscHN6Q2xhc3MsCglMUERXT1JECWxwY2NoQ2xhc3MsCglGSUxFVElNRQkqZnQKKSB7CglEV09SRAlyZXQsbHBjY2hOYW1lVyxscGNjaENsYXNzVzsKCUxQV1NUUglscHN6TmFtZVcsbHBzekNsYXNzVzsKCgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5RXgzMkEoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbi0+IiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglpZiAobHBzek5hbWUpIHsKCQlscHN6TmFtZVcJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoTmFtZSoyKTsKCQlscGNjaE5hbWVXCT0gKmxwY2NoTmFtZSoyOwoJfSBlbHNlIHsKCQlscHN6TmFtZVcJPSBOVUxMOwoJCWxwY2NoTmFtZVcgCT0gMDsKCX0KCWlmIChscHN6Q2xhc3MpIHsKCQlscHN6Q2xhc3NXCQk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyoyKTsKCQlscGNjaENsYXNzVwk9ICpscGNjaENsYXNzKjI7Cgl9IGVsc2UgewoJCWxwc3pDbGFzc1cJPTA7CgkJbHBjY2hDbGFzc1c9MDsKCX0KCXJldD1SZWdFbnVtS2V5RXgzMlcoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lVywKCQkmbHBjY2hOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQkmbHBjY2hDbGFzc1csCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzek5hbWUsbHBzek5hbWVXKTsKCQkqbHBjY2hOYW1lPXN0cmxlbihscHN6TmFtZSk7CgkJaWYgKGxwc3pDbGFzc1cpIHsKCQkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJCQkqbHBjY2hDbGFzcz1zdHJsZW4obHBzekNsYXNzKTsKCQl9Cgl9CglpZiAobHBzek5hbWVXKQoJCWZyZWUobHBzek5hbWVXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdFbnVtS2V5QQkJCVtBRFZBUEkzMi4xMzddICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQU1RSCWxwc3pOYW1lLAoJRFdPUkQJbHBjY2hOYW1lCikgewoJRklMRVRJTUUJZnQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5MzJBKCV4LCVsZCwlcCwlbGQpXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZQoJKTsKCXJldHVybglSZWdFbnVtS2V5RXgzMkEoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lLAoJCSZscGNjaE5hbWUsCgkJTlVMTCwKCQlOVUxMLAoJCU5VTEwsCgkJJmZ0CgkpOwp9CgovKiBSZWdFbnVtS2V5CQkJW1NIRUxMLjddIFtLRVJORUwuMjE2XSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQU1RSCWxwc3pOYW1lLAoJRFdPUkQJbHBjY2hOYW1lCikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5MTYoJXgsJWxkLCVwLCVsZClcbi0+IiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lCgkpOwoJcmV0dXJuIFJlZ0VudW1LZXkzMkEoaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7Cn0KCi8qIAogKiBFbnVtZXJhdGUgUmVnaXN0cnkgVmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtVmFsdWUxNiAtPiBSZWdFbnVtVmFsdWUzMkEgLT4gUmVnRW51bVZhbHVlMzJXCiAqLwoKLyogUmVnRW51bVZhbHVlVwkJW0FEVkFQSTMyLjE0Ml0gKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTMyVygKCUhLRVkJaGtleSwKCURXT1JECWlWYWx1ZSwKCUxQV1NUUglscHN6VmFsdWUsCglMUERXT1JECWxwY2NoVmFsdWUsCglMUERXT1JECWxwZFJlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtVmFsdWUzMlcoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhCgkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmIChscGtleS0+bnJvZnZhbHVlczw9aVZhbHVlKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJdmFsCT0gbHBrZXktPnZhbHVlcytpVmFsdWU7CgoJaWYgKHZhbC0+bmFtZSkgewoJCWlmIChsc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyPipscGNjaFZhbHVlKSB7CgkJCSpscGNjaFZhbHVlID0gbHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMjsKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQl9CgkJbWVtY3B5KGxwc3pWYWx1ZSx2YWwtPm5hbWUsMipsc3RybGVuMzJXKHZhbC0+bmFtZSkrMik7CgkJKmxwY2NoVmFsdWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMjsKCX0gZWxzZSB7CgkJLyogaG93IHRvIGhhbmRsZSBOVUxMIHZhbHVlPyAqLwoJCSpscHN6VmFsdWUJPSAwOwoJCSpscGNjaFZhbHVlCT0gMjsKCX0KCSpscGR3VHlwZT12YWwtPnR5cGU7CglpZiAobHBiRGF0YSkgewoJCWlmICh2YWwtPmxlbj4qbHBjYkRhdGEpCgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJbWVtY3B5KGxwYkRhdGEsdmFsLT5kYXRhLHZhbC0+bGVuKTsKCQkqbHBjYkRhdGEgPSB2YWwtPmxlbjsKCX0KCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdFbnVtVmFsdWVBCQlbQURWQVBJMzIuMTQxXSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVZhbHVlLAoJTFBTVFIJbHBzelZhbHVlLAoJTFBEV09SRAlscGNjaFZhbHVlLAoJTFBEV09SRAlscGRSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUFdTVFIJbHBzelZhbHVlVzsKCUxQQllURQlscGJEYXRhVzsKCURXT1JECXJldCxscGNiRGF0YVc7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtVmFsdWUzMkEoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhCgkpOwoKCWxwc3pWYWx1ZVcgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoVmFsdWUqMik7CglpZiAobHBiRGF0YSkgewoJCWxwYkRhdGFXID0gKExQQllURSl4bWFsbG9jKCpscGNiRGF0YSoyKTsKCQlscGNiRGF0YVcgPSAqbHBjYkRhdGEqMjsKCX0gZWxzZQoJCWxwYkRhdGFXID0gTlVMTDsKCXJldD1SZWdFbnVtVmFsdWUzMlcoCgkJaGtleSwKCQlpVmFsdWUsCgkJbHBzelZhbHVlVywKCQlscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLAoJCWxwZHdUeXBlLAoJCWxwYkRhdGFXLAoJCSZscGNiRGF0YVcKCSk7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pWYWx1ZSxscHN6VmFsdWVXKTsKCQlpZiAobHBiRGF0YSkgewoJCQlpZiAoKDE8PCpscGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWxwYkRhdGFXKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChscGNiRGF0YVcgPiAqbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGxwYkRhdGFXLGxwY2JEYXRhVyk7CgkJCX0KCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCX0KCX0KCWlmIChscGJEYXRhVykKCQlmcmVlKGxwYkRhdGFXKTsKCWlmIChscHN6VmFsdWVXKQoJCWZyZWUobHBzelZhbHVlVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdFbnVtVmFsdWUJCQlbS0VSTkVMLjIyM10gKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTE2KAoJSEtFWQloa2V5LAoJRFdPUkQJaVZhbHVlLAoJTFBTVFIJbHBzelZhbHVlLAoJTFBEV09SRAlscGNjaFZhbHVlLAoJTFBEV09SRAlscGRSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0VudW1WYWx1ZSgleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEKCSk7CglyZXR1cm4gUmVnRW51bVZhbHVlMzJBKAoJCWhrZXksCgkJaVZhbHVlLAoJCWxwc3pWYWx1ZSwKCQlscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLAoJCWxwZHdUeXBlLAoJCWxwYkRhdGEsCgkJbHBjYkRhdGEKCSk7Cn0KCi8qIAogKiAgQ2xvc2UgcmVnaXN0cnkga2V5CiAqLwovKiBSZWdDbG9zZUtleQkJCVtTSEVMTC4zXSBbS0VSTkVMLjIyMF0gW0FEVkFQSTMyLjEyNl0gKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5KEhLRVkgaGtleSkgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDbG9zZUtleSgleClcbiIsaGtleSk7CglyZW1vdmVfaGFuZGxlKGhrZXkpOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCi8qIFJlZ0RlbGV0ZUtleVcJCVtBRFZBUEkzMi4xMzRdICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMlcoSEtFWSBoa2V5LExQV1NUUiBscHN6U3ViS2V5KSB7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdEZWxldGVLZXkzMlcoJXgsJXMpXG4iLAoJCWhrZXksVzJDKGxwc3pTdWJLZXksMCkKCSk7CglscE5leHRLZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBOZXh0S2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgkvKiB3ZSBuZWVkIHRvIGtub3cgdGhlIHByZXZpb3VzIGtleSBpbiB0aGUgaGllci4gKi8KCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKGk8d3BjLTEpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQkvKiBub3QgZm91bmQgaXMgc3VjY2VzcyAqLwoJCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCQl9CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWxweGtleQk9IGxwTmV4dEtleS0+bmV4dHN1YjsKCWxwbHBQcmV2S2V5ID0gJihscE5leHRLZXktPm5leHRzdWIpOwoJd2hpbGUgKGxweGtleSkgewoJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQkJPSBscHhrZXktPm5leHQ7Cgl9CglpZiAoIWxweGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCWlmIChscHhrZXktPm5leHRzdWIpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0NBTlRXUklURTsKCSpscGxwUHJldktleQk9IGxweGtleS0+bmV4dDsKCWZyZWUobHB4a2V5LT5rZXluYW1lKTsKCWlmIChscHhrZXktPmNsYXNzKQoJCWZyZWUobHB4a2V5LT5jbGFzcyk7CglpZiAobHB4a2V5LT52YWx1ZXMpCgkJZnJlZShscHhrZXktPnZhbHVlcyk7CglmcmVlKGxweGtleSk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuCVNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0RlbGV0ZUtleUEJCVtBRFZBUEkzMi4xMzNdICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMkEoSEtFWSBoa2V5LExQQ1NUUiBscHN6U3ViS2V5KSB7CglMUFdTVFIJbHBzelN1YktleVc7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdEZWxldGVLZXkzMkEoJXgsJXMpXG4iLAoJCWhrZXksbHBzelN1YktleQoJKTsKCWxwc3pTdWJLZXlXPUhFQVBfc3RyZHVwQXRvVyhHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelN1YktleSk7CglyZXQ9UmVnRGVsZXRlS2V5MzJXKGhrZXksbHBzelN1YktleVcpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pTdWJLZXlXKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ0RlbGV0ZUtleQkJCVtTSEVMTC40XSBbS0VSTkVMLjIxOV0gKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KEhLRVkgaGtleSxMUENTVFIgbHBzelN1YktleSkgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdEZWxldGVLZXkxNigleCwlcylcbiIsCgkJaGtleSxscHN6U3ViS2V5CgkpOwoJcmV0dXJuIFJlZ0RlbGV0ZUtleTMyQShoa2V5LGxwc3pTdWJLZXkpOwp9CgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVWYWx1ZTE2IC0+IFJlZ0RlbGV0ZVZhbHVlMzJBIC0+IFJlZ0RlbGV0ZVZhbHVlMzJXCiAqLwovKiBSZWdEZWxldGVWYWx1ZVcJCVtBRFZBUEkzMi4xMzZdICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyVyhIS0VZIGhrZXksTFBXU1RSIGxwc3pWYWx1ZSkKewoJRFdPUkQJCWk7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRGVsZXRlVmFsdWUzMlcoJXgsJXMpXG4iLAoJCWhrZXksVzJDKGxwc3pWYWx1ZSwwKQoJKTsKCWxwa2V5PWxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKGxwc3pWYWx1ZSkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwa2V5LT52YWx1ZXNbaV0ubmFtZSxscHN6VmFsdWUpCgkJCSkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7LypGSVhNRTogY29ycmVjdCBlcnJvcmNvZGU/ICovCgl2YWwJPSBscGtleS0+dmFsdWVzK2k7CglpZiAodmFsLT5uYW1lKSBmcmVlKHZhbC0+bmFtZSk7CglpZiAodmFsLT5kYXRhKSBmcmVlKHZhbC0+ZGF0YSk7CgltZW1jcHkoCQoJCWxwa2V5LT52YWx1ZXMraSwKCQlscGtleS0+dmFsdWVzK2krMSwKCQlzaXplb2YoS0VZVkFMVUUpKihscGtleS0+bnJvZnZhbHVlcy1pLTEpCgkpOwoJbHBrZXktPnZhbHVlcwk9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJbHBrZXktPnZhbHVlcywKCQkJCShscGtleS0+bnJvZnZhbHVlcy0xKSpzaXplb2YoS0VZVkFMVUUpCgkJCSk7CglscGtleS0+bnJvZnZhbHVlcy0tOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0RlbGV0ZVZhbHVlQQkJW0FEVkFQSTMyLjEzNV0gKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMzJBKEhLRVkgaGtleSxMUFNUUiBscHN6VmFsdWUpCnsKCUxQV1NUUglscHN6VmFsdWVXOwoJRFdPUkQJcmV0OwoKCWRwcmludGZfcmVnKCBzdGRkZWIsICJSZWdEZWxldGVWYWx1ZTMyQSgleCwlcylcbiIsIGhrZXksbHBzelZhbHVlICk7CiAgICAgICAgbHBzelZhbHVlVz1IRUFQX3N0cmR1cEF0b1coR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pWYWx1ZSk7CglyZXQ9UmVnRGVsZXRlVmFsdWUzMlcoaGtleSxscHN6VmFsdWVXKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelZhbHVlVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdEZWxldGVWYWx1ZQkJW0tFUk5FTC4yMjJdICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KEhLRVkgaGtleSxMUFNUUiBscHN6VmFsdWUpCnsKCWRwcmludGZfcmVnKCBzdGRkZWIsIlJlZ0RlbGV0ZVZhbHVlMTYoJXgsJXMpXG4iLCBoa2V5LGxwc3pWYWx1ZSApOwoJcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlMzJBKGhrZXksbHBzelZhbHVlKTsKfQoKLyogUmVnRmx1c2hLZXkJCQlbQURWQVBJMzIuMTQzXSBbS0VSTkVMLjIyN10gKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KEhLRVkgaGtleSkKewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdGbHVzaEtleSgleCksIFNUVUIuXG4iLGhrZXkpOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIEZJWE1FOiBscGNjaFhYWFggLi4uIGlzIHRoaXMgY291bnRpbmcgaW4gV0NIQVJTIG9yIGluIEJZVEVzID8/ICovCgovKiBSZWdRdWVyeUluZm9LZXlXCQlbQURWQVBJMzIuMTUzXSAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pDbGFzcywKCUxQRFdPUkQJbHBjY2hDbGFzcywKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGNTdWJLZXlzLAoJTFBEV09SRAlscGNjaE1heFN1YmtleSwKCUxQRFdPUkQJbHBjY2hNYXhDbGFzcywKCUxQRFdPUkQJbHBjVmFsdWVzLAoJTFBEV09SRAlscGNjaE1heFZhbHVlTmFtZSwKCUxQRFdPUkQJbHBjY2JNYXhWYWx1ZURhdGEsCglMUERXT1JECWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCglGSUxFVElNRQkqZnQKKSB7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CglpbnQJCW5yb2ZrZXlzLG1heHN1YmtleSxtYXhjbGFzcyxtYXh2YWx1ZXMsbWF4dm5hbWUsbWF4dmRhdGE7CglpbnQJCWk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdRdWVyeUluZm9LZXkzMlcoJXgsLi4uLi4uKVxuIixoa2V5KTsKCWxwa2V5PWxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKGxwc3pDbGFzcykgewoJCWlmIChscGtleS0+Y2xhc3MpIHsKCQkJaWYgKGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyKzI+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQkJfQoJCQkqbHBjY2hDbGFzcz1sc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCQkJbWVtY3B5KGxwc3pDbGFzcyxscGtleS0+Y2xhc3MsbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKTsKCQl9IGVsc2UgewoJCQkqbHBzekNsYXNzCT0gMDsKCQkJKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7Cgl9CglscHhrZXk9bHBrZXktPm5leHRzdWI7Cglucm9ma2V5cz1tYXhzdWJrZXk9bWF4Y2xhc3M9bWF4dmFsdWVzPW1heHZuYW1lPW1heHZkYXRhPTA7Cgl3aGlsZSAobHB4a2V5KSB7CgkJbnJvZmtleXMrKzsKCQlpZiAobHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpPm1heHN1YmtleSkKCQkJbWF4c3Via2V5PWxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKTsKCQlpZiAobHB4a2V5LT5jbGFzcyAmJiBsc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpPm1heGNsYXNzKQoJCQltYXhjbGFzcz1sc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpOwoJCWlmIChscHhrZXktPm5yb2Z2YWx1ZXM+bWF4dmFsdWVzKQoJCQltYXh2YWx1ZXM9bHB4a2V5LT5ucm9mdmFsdWVzOwoJCWZvciAoaT0wO2k8bHB4a2V5LT5ucm9mdmFsdWVzO2krKykgewoJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJaWYgKHZhbC0+bmFtZSAmJiBsc3RybGVuMzJXKHZhbC0+bmFtZSk+bWF4dm5hbWUpCgkJCQltYXh2bmFtZT1sc3RybGVuMzJXKHZhbC0+bmFtZSk7CgkJCWlmICh2YWwtPmxlbj5tYXh2ZGF0YSkKCQkJCW1heHZkYXRhPXZhbC0+bGVuOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJaWYgKCFtYXhjbGFzcykgbWF4Y2xhc3MJPSAxOwoJaWYgKCFtYXh2bmFtZSkgbWF4dm5hbWUJPSAxOwoJaWYgKGxwY1N1YktleXMpCgkJKmxwY1N1YktleXMJPSBucm9ma2V5czsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkJPSBtYXhzdWJrZXkqMjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzCT0gbWF4Y2xhc3MqMjsKCWlmIChscGNWYWx1ZXMpCgkJKmxwY1ZhbHVlcwk9IG1heHZhbHVlczsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWU9IG1heHZuYW1lOwoJaWYgKGxwY2NiTWF4VmFsdWVEYXRhKQoJCSpscGNjYk1heFZhbHVlRGF0YT0gbWF4dmRhdGE7CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnUXVlcnlJbmZvS2V5QQkJW0FEVkFQSTMyLjE1Ml0gKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleTMyQSgKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pDbGFzcywKCUxQRFdPUkQJbHBjY2hDbGFzcywKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGNTdWJLZXlzLAoJTFBEV09SRAlscGNjaE1heFN1YmtleSwKCUxQRFdPUkQJbHBjY2hNYXhDbGFzcywKCUxQRFdPUkQJbHBjVmFsdWVzLAoJTFBEV09SRAlscGNjaE1heFZhbHVlTmFtZSwKCUxQRFdPUkQJbHBjY2JNYXhWYWx1ZURhdGEsCglMUERXT1JECWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCglGSUxFVElNRQkqZnQKKSB7CglMUFdTVFIJCWxwc3pDbGFzc1c7CglEV09SRAkJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlJbmZvS2V5MzJBKCV4LC4uLi4uLilcbiIsaGtleSk7CglpZiAobHBzekNsYXNzKSB7CgkJKmxwY2NoQ2xhc3MqPSAyOwoJCWxwc3pDbGFzc1cgID0gKExQV1NUUil4bWFsbG9jKCpscGNjaENsYXNzKTsKCgl9IGVsc2UKCQlscHN6Q2xhc3NXICA9IE5VTEw7CglyZXQ9UmVnUXVlcnlJbmZvS2V5MzJXKAoJCWhrZXksCgkJbHBzekNsYXNzVywKCQlscGNjaENsYXNzLAoJCWxwZHdSZXNlcnZlZCwKCQlscGNTdWJLZXlzLAoJCWxwY2NoTWF4U3Via2V5LAoJCWxwY2NoTWF4Q2xhc3MsCgkJbHBjVmFsdWVzLAoJCWxwY2NoTWF4VmFsdWVOYW1lLAoJCWxwY2NiTWF4VmFsdWVEYXRhLAoJCWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTICYmIGxwc3pDbGFzcykKCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CglpZiAobHBjY2hDbGFzcykKCQkqbHBjY2hDbGFzcy89MjsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkvPTI7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcy89MjsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWUvPTI7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQovKiBSZWdDb25uZWN0UmVnaXN0cnlBCQlbQURWQVBJMzIuMTI3XSAqLwpEV09SRCBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBKExQQ1NUUiBtYWNoaW5lLEhLRVkgaGtleSxMUEhLRVkgcmVza2V5KQp7CglmcHJpbnRmKHN0ZGVyciwiUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBKCVzLCUwOHgsJXApLCBTVFVCLlxuIiwKCQltYWNoaW5lLGhrZXkscmVza2V5CgkpOwoJcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOyAvKiBGSVhNRSAqLwp9Cg==