LyoKICogQ29weXJpZ2h0IChjKSAyMDAyIEp1aGEgWXJq9mzkLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogQ29weXJpZ2h0IChjKSAyMDAxIE1hcmt1cyBGcmllZGwuCiAqIAogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTUyBPUgogKiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwKICogSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUCiAqIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GCiAqIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqLwoKI2luY2x1ZGUgImluY2x1ZGVzLmgiCiNpZiBkZWZpbmVkKFNNQVJUQ0FSRCkgJiYgZGVmaW5lZChVU0VfT1BFTlNDKQoKI2luY2x1ZGUgPG9wZW5zc2wvZXZwLmg+CiNpbmNsdWRlIDxvcGVuc3NsL3g1MDkuaD4KCiNpbmNsdWRlIDxvcGVuc2Mvb3BlbnNjLmg+CiNpbmNsdWRlIDxvcGVuc2MvcGtjczE1Lmg+CgojaW5jbHVkZSAia2V5LmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgInJlYWRwYXNzLmgiCiNpbmNsdWRlICJzY2FyZC5oIgoKI2lmIE9QRU5TU0xfVkVSU0lPTl9OVU1CRVIgPCAweDAwOTA3MDAwTCAmJiBkZWZpbmVkKENSWVBUT19MT0NLX0VOR0lORSkKI2RlZmluZSBVU0VfRU5HSU5FCiNkZWZpbmUgUlNBX2dldF9kZWZhdWx0X21ldGhvZCBSU0FfZ2V0X2RlZmF1bHRfb3BlbnNzbF9tZXRob2QKI2Vsc2UKI2VuZGlmCgojaWZkZWYgVVNFX0VOR0lORQojaW5jbHVkZSA8b3BlbnNzbC9lbmdpbmUuaD4KI2RlZmluZSBzY19nZXRfcnNhIHNjX2dldF9lbmdpbmUKI2Vsc2UKI2RlZmluZSBzY19nZXRfcnNhIHNjX2dldF9yc2FfbWV0aG9kCiNlbmRpZgoKc3RhdGljIGludCBzY19yZWFkZXJfaWQ7CnN0YXRpYyBzY19jb250ZXh0X3QgKmN0eCA9IE5VTEw7CnN0YXRpYyBzY19jYXJkX3QgKmNhcmQgPSBOVUxMOwpzdGF0aWMgc2NfcGtjczE1X2NhcmRfdCAqcDE1Y2FyZCA9IE5VTEw7CgpzdGF0aWMgY2hhciAqc2NfcGluID0gTlVMTDsKCnN0cnVjdCBzY19wcml2X2RhdGEKewoJc3RydWN0IHNjX3BrY3MxNV9pZCBjZXJ0X2lkOwoJaW50IHJlZl9jb3VudDsKfTsKCnZvaWQKc2NfY2xvc2Uodm9pZCkKewoJaWYgKHAxNWNhcmQpIHsKCQlzY19wa2NzMTVfdW5iaW5kKHAxNWNhcmQpOwoJCXAxNWNhcmQgPSBOVUxMOwoJfQoJaWYgKGNhcmQpIHsKCQlzY19kaXNjb25uZWN0X2NhcmQoY2FyZCwgMCk7CgkJY2FyZCA9IE5VTEw7Cgl9CglpZiAoY3R4KSB7CgkJc2NfcmVsZWFzZV9jb250ZXh0KGN0eCk7CgkJY3R4ID0gTlVMTDsKCX0KfQoKc3RhdGljIGludCAKc2NfaW5pdCh2b2lkKQp7CglpbnQgcjsKCglyID0gc2NfZXN0YWJsaXNoX2NvbnRleHQoJmN0eCwgIm9wZW5zc2giKTsKCWlmIChyKQoJCWdvdG8gZXJyOwoJaWYgKHNjX3JlYWRlcl9pZCA+PSBjdHgtPnJlYWRlcl9jb3VudCkgewoJCXIgPSBTQ19FUlJPUl9OT19SRUFERVJTX0ZPVU5EOwoJCWVycm9yKCJJbGxlZ2FsIHJlYWRlciBudW1iZXIgJWQgKG1heCAlZCkiLCBzY19yZWFkZXJfaWQsIAoJCSAgICBjdHgtPnJlYWRlcl9jb3VudCAtMSk7CgkJZ290byBlcnI7Cgl9CglyID0gc2NfY29ubmVjdF9jYXJkKGN0eC0+cmVhZGVyW3NjX3JlYWRlcl9pZF0sIDAsICZjYXJkKTsKCWlmIChyKQoJCWdvdG8gZXJyOwoJciA9IHNjX3BrY3MxNV9iaW5kKGNhcmQsICZwMTVjYXJkKTsKCWlmIChyKQoJCWdvdG8gZXJyOwoJcmV0dXJuIDA7CmVycjoKCXNjX2Nsb3NlKCk7CglyZXR1cm4gcjsKfQoKLyogcHJpdmF0ZSBrZXkgb3BlcmF0aW9ucyAqLwoKc3RhdGljIGludApzY19wcmtleV9vcF9pbml0KFJTQSAqcnNhLCBzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqKmtleV9vYmpfb3V0KQp7CglpbnQgcjsKCXN0cnVjdCBzY19wcml2X2RhdGEgKnByaXY7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCXN0cnVjdCBzY19wa2NzMTVfcHJrZXlfaW5mbyAqa2V5OwoJc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKnBpbl9vYmo7CglzdHJ1Y3Qgc2NfcGtjczE1X3Bpbl9pbmZvICpwaW47CgoJcHJpdiA9IChzdHJ1Y3Qgc2NfcHJpdl9kYXRhICopIFJTQV9nZXRfYXBwX2RhdGEocnNhKTsKCWlmIChwcml2ID09IE5VTEwpCgkJcmV0dXJuIC0xOwoJaWYgKHAxNWNhcmQgPT0gTlVMTCkgewoJCXNjX2Nsb3NlKCk7CgkJciA9IHNjX2luaXQoKTsKCQlpZiAocikgewoJCQllcnJvcigiU21hcnRDYXJkIGluaXQgZmFpbGVkOiAlcyIsIHNjX3N0cmVycm9yKHIpKTsKCQkJZ290byBlcnI7CgkJfQoJfQoJciA9IHNjX3BrY3MxNV9maW5kX3Bya2V5X2J5X2lkKHAxNWNhcmQsICZwcml2LT5jZXJ0X2lkLCAma2V5X29iaik7CglpZiAocikgewoJCWVycm9yKCJVbmFibGUgdG8gZmluZCBwcml2YXRlIGtleSBmcm9tIFNtYXJ0Q2FyZDogJXMiLAoJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQlnb3RvIGVycjsKCX0KCWtleSA9IGtleV9vYmotPmRhdGE7CglyID0gc2NfcGtjczE1X2ZpbmRfcGluX2J5X2F1dGhfaWQocDE1Y2FyZCwgJmtleV9vYmotPmF1dGhfaWQsCgkJCQkJICAmcGluX29iaik7CglpZiAociA9PSBTQ19FUlJPUl9PQkpFQ1RfTk9UX0ZPVU5EKSB7CgkJLyogbm8gcGluIHJlcXVpcmVkICovCgkJciA9IHNjX2xvY2soY2FyZCk7CgkJaWYgKHIpIHsKCQkJZXJyb3IoIlVuYWJsZSB0byBsb2NrIHNtYXJ0Y2FyZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCQkqa2V5X29ial9vdXQgPSBrZXlfb2JqOwoJCXJldHVybiAwOwoJfSBlbHNlIGlmIChyKSB7CgkJZXJyb3IoIlVuYWJsZSB0byBmaW5kIFBJTiBvYmplY3QgZnJvbSBTbWFydENhcmQ6ICVzIiwKCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9CglwaW4gPSBwaW5fb2JqLT5kYXRhOwoJciA9IHNjX2xvY2soY2FyZCk7CglpZiAocikgewoJCWVycm9yKCJVbmFibGUgdG8gbG9jayBzbWFydGNhcmQ6ICVzIiwgc2Nfc3RyZXJyb3IocikpOwoJCWdvdG8gZXJyOwoJfQoJaWYgKHNjX3BpbiAhPSBOVUxMKSB7CgkJciA9IHNjX3BrY3MxNV92ZXJpZnlfcGluKHAxNWNhcmQsIHBpbiwgc2NfcGluLAoJCQkJCSBzdHJsZW4oc2NfcGluKSk7CgkJaWYgKHIpIHsKCQkJc2NfdW5sb2NrKGNhcmQpOwoJCQllcnJvcigiUElOIGNvZGUgdmVyaWZpY2F0aW9uIGZhaWxlZDogJXMiLAoJCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCX0KCSprZXlfb2JqX291dCA9IGtleV9vYmo7CglyZXR1cm4gMDsKZXJyOgoJc2NfY2xvc2UoKTsKCXJldHVybiAtMTsKfQoKc3RhdGljIGludApzY19wcml2YXRlX2RlY3J5cHQoaW50IGZsZW4sIHVfY2hhciAqZnJvbSwgdV9jaGFyICp0bywgUlNBICpyc2EsCiAgICBpbnQgcGFkZGluZykKewoJc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKmtleV9vYmo7CglpbnQgcjsKCglpZiAocGFkZGluZyAhPSBSU0FfUEtDUzFfUEFERElORykKCQlyZXR1cm4gLTE7CQoJciA9IHNjX3Bya2V5X29wX2luaXQocnNhLCAma2V5X29iaik7CglpZiAocikKCQlyZXR1cm4gLTE7CglyID0gc2NfcGtjczE1X2RlY2lwaGVyKHAxNWNhcmQsIGtleV9vYmosIFNDX0FMR09SSVRITV9SU0FfUEFEX1BLQ1MxLCAKCSAgICBmcm9tLCBmbGVuLCB0bywgZmxlbik7CglzY191bmxvY2soY2FyZCk7CglpZiAociA8IDApIHsKCQllcnJvcigic2NfcGtjczE1X2RlY2lwaGVyKCkgZmFpbGVkOiAlcyIsIHNjX3N0cmVycm9yKHIpKTsKCQlnb3RvIGVycjsKCX0KCXJldHVybiByOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50CnNjX3NpZ24oaW50IHR5cGUsIHVfY2hhciAqbSwgdW5zaWduZWQgaW50IG1fbGVuLAoJdW5zaWduZWQgY2hhciAqc2lncmV0LCB1bnNpZ25lZCBpbnQgKnNpZ2xlbiwgUlNBICpyc2EpCnsKCXN0cnVjdCBzY19wa2NzMTVfb2JqZWN0ICprZXlfb2JqOwoJaW50IHI7Cgl1bnNpZ25lZCBsb25nIGZsYWdzID0gMDsKCglyID0gc2NfcHJrZXlfb3BfaW5pdChyc2EsICZrZXlfb2JqKTsKCWlmIChyKQoJCXJldHVybiAtMTsKCS8qIEZJWE1FOiBsZW5ndGggb2Ygc2lncmV0IGNvcnJlY3Q/ICovCgkvKiBGSVhNRTogY2hlY2sgJ3R5cGUnIGFuZCBtb2RpZnkgZmxhZ3MgYWNjb3JkaW5nbHkgKi8KCWZsYWdzID0gU0NfQUxHT1JJVEhNX1JTQV9QQURfUEtDUzEgfCBTQ19BTEdPUklUSE1fUlNBX0hBU0hfU0hBMTsKCXIgPSBzY19wa2NzMTVfY29tcHV0ZV9zaWduYXR1cmUocDE1Y2FyZCwga2V5X29iaiwgZmxhZ3MsCgkJCQkJbSwgbV9sZW4sIHNpZ3JldCwgUlNBX3NpemUocnNhKSk7CglzY191bmxvY2soY2FyZCk7CglpZiAociA8IDApIHsKCQllcnJvcigic2NfcGtjczE1X2NvbXB1dGVfc2lnbmF0dXJlKCkgZmFpbGVkOiAlcyIsCgkJICAgICAgc2Nfc3RyZXJyb3IocikpOwoJCWdvdG8gZXJyOwoJfQoJKnNpZ2xlbiA9IHI7CglyZXR1cm4gMTsKZXJyOgoJc2NfY2xvc2UoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50CnNjX3ByaXZhdGVfZW5jcnlwdChpbnQgZmxlbiwgdV9jaGFyICpmcm9tLCB1X2NoYXIgKnRvLCBSU0EgKnJzYSwKICAgIGludCBwYWRkaW5nKQp7CgllcnJvcigiUHJpdmF0ZSBrZXkgZW5jcnlwdGlvbiBub3Qgc3VwcG9ydGVkIik7CglyZXR1cm4gLTE7Cn0KCi8qIGNhbGxlZCBvbiBmcmVlICovCgpzdGF0aWMgaW50ICgqb3JpZ19maW5pc2gpKFJTQSAqcnNhKSA9IE5VTEw7CgpzdGF0aWMgaW50CnNjX2ZpbmlzaChSU0EgKnJzYSkKewoJc3RydWN0IHNjX3ByaXZfZGF0YSAqcHJpdjsKCglwcml2ID0gUlNBX2dldF9hcHBfZGF0YShyc2EpOwoJcHJpdi0+cmVmX2NvdW50LS07CglpZiAocHJpdi0+cmVmX2NvdW50ID09IDApIHsKCQlmcmVlKHByaXYpOwoJCXNjX2Nsb3NlKCk7Cgl9CglpZiAob3JpZ19maW5pc2gpCgkJb3JpZ19maW5pc2gocnNhKTsKCXJldHVybiAxOwp9CgovKiBlbmdpbmUgZm9yIG92ZXJsb2FkaW5nIHByaXZhdGUga2V5IG9wZXJhdGlvbnMgKi8KCnN0YXRpYyBSU0FfTUVUSE9EICoKc2NfZ2V0X3JzYV9tZXRob2Qodm9pZCkKewoJc3RhdGljIFJTQV9NRVRIT0Qgc21hcnRfcnNhOwoJY29uc3QgUlNBX01FVEhPRCAqZGVmID0gUlNBX2dldF9kZWZhdWx0X21ldGhvZCgpOwoKCS8qIHVzZSB0aGUgT3BlblNTTCB2ZXJzaW9uICovCgltZW1jcHkoJnNtYXJ0X3JzYSwgZGVmLCBzaXplb2Yoc21hcnRfcnNhKSk7CgoJc21hcnRfcnNhLm5hbWUJCT0gIm9wZW5zYyI7CgoJLyogb3ZlcmxvYWQgKi8KCXNtYXJ0X3JzYS5yc2FfcHJpdl9lbmMJPSBzY19wcml2YXRlX2VuY3J5cHQ7CglzbWFydF9yc2EucnNhX3ByaXZfZGVjCT0gc2NfcHJpdmF0ZV9kZWNyeXB0OwoJc21hcnRfcnNhLnJzYV9zaWduCT0gc2Nfc2lnbjsKCgkvKiBzYXZlIG9yaWdpbmFsICovCglvcmlnX2ZpbmlzaAkJPSBkZWYtPmZpbmlzaDsKCXNtYXJ0X3JzYS5maW5pc2gJPSBzY19maW5pc2g7CgoJcmV0dXJuICZzbWFydF9yc2E7Cn0KCiNpZmRlZiBVU0VfRU5HSU5FCnN0YXRpYyBFTkdJTkUgKgpzY19nZXRfZW5naW5lKHZvaWQpCnsKCXN0YXRpYyBFTkdJTkUgKnNtYXJ0X2VuZ2luZSA9IE5VTEw7CgoJaWYgKChzbWFydF9lbmdpbmUgPSBFTkdJTkVfbmV3KCkpID09IE5VTEwpCgkJZmF0YWwoIkVOR0lORV9uZXcgZmFpbGVkIik7CgoJRU5HSU5FX3NldF9pZChzbWFydF9lbmdpbmUsICJvcGVuc2MiKTsKCUVOR0lORV9zZXRfbmFtZShzbWFydF9lbmdpbmUsICJPcGVuU0MiKTsKCglFTkdJTkVfc2V0X1JTQShzbWFydF9lbmdpbmUsIHNjX2dldF9yc2FfbWV0aG9kKCkpOwoJRU5HSU5FX3NldF9EU0Eoc21hcnRfZW5naW5lLCBEU0FfZ2V0X2RlZmF1bHRfb3BlbnNzbF9tZXRob2QoKSk7CglFTkdJTkVfc2V0X0RIKHNtYXJ0X2VuZ2luZSwgREhfZ2V0X2RlZmF1bHRfb3BlbnNzbF9tZXRob2QoKSk7CglFTkdJTkVfc2V0X1JBTkQoc21hcnRfZW5naW5lLCBSQU5EX1NTTGVheSgpKTsKCUVOR0lORV9zZXRfQk5fbW9kX2V4cChzbWFydF9lbmdpbmUsIEJOX21vZF9leHApOwoKCXJldHVybiBzbWFydF9lbmdpbmU7Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZApjb252ZXJ0X3JzYV90b19yc2ExKEtleSAqIGluLCBLZXkgKiBvdXQpCnsKCXN0cnVjdCBzY19wcml2X2RhdGEgKnByaXY7CgkKCW91dC0+cnNhLT5mbGFncyA9IGluLT5yc2EtPmZsYWdzOwoJb3V0LT5mbGFncyA9IGluLT5mbGFnczsKCVJTQV9zZXRfbWV0aG9kKG91dC0+cnNhLCBSU0FfZ2V0X21ldGhvZChpbi0+cnNhKSk7CglCTl9jb3B5KG91dC0+cnNhLT5uLCBpbi0+cnNhLT5uKTsKCUJOX2NvcHkob3V0LT5yc2EtPmUsIGluLT5yc2EtPmUpOwoJcHJpdiA9IFJTQV9nZXRfYXBwX2RhdGEoaW4tPnJzYSk7Cglwcml2LT5yZWZfY291bnQrKzsKCVJTQV9zZXRfYXBwX2RhdGEob3V0LT5yc2EsIHByaXYpOwoJcmV0dXJuOwp9CgpzdGF0aWMgaW50IApzY19yZWFkX3B1YmtleShLZXkgKiBrLCBjb25zdCBzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqY2VydF9vYmopCnsKCWludCByOwoJc2NfcGtjczE1X2NlcnRfdCAqY2VydCA9IE5VTEw7CglzdHJ1Y3Qgc2NfcHJpdl9kYXRhICpwcml2ID0gTlVMTDsKCXNjX3BrY3MxNV9jZXJ0X2luZm9fdCAqY2luZm8gPSBjZXJ0X29iai0+ZGF0YTsKCglYNTA5ICp4NTA5ID0gTlVMTDsKCUVWUF9QS0VZICpwdWJrZXkgPSBOVUxMOwoJdTggKnA7CgljaGFyICp0bXA7CgkKCWRlYnVnKCJzY19yZWFkX3B1YmtleSgpIHdpdGggY2VydCBpZCAlMDJYIiwgY2luZm8tPmlkLnZhbHVlWzBdKTsKCXIgPSBzY19wa2NzMTVfcmVhZF9jZXJ0aWZpY2F0ZShwMTVjYXJkLCBjaW5mbywgJmNlcnQpOwoJaWYgKHIpIHsKCQlsb2dpdCgiQ2VydGlmaWNhdGUgcmVhZCBmYWlsZWQ6ICVzIiwgc2Nfc3RyZXJyb3IocikpOwoJCWdvdG8gZXJyOwoJfQoJeDUwOSA9IFg1MDlfbmV3KCk7CglpZiAoeDUwOSA9PSBOVUxMKSB7CgkJciA9IC0xOyAKCQlnb3RvIGVycjsKCX0KCXAgPSBjZXJ0LT5kYXRhOwoJaWYgKCFkMmlfWDUwOSgmeDUwOSwgJnAsIGNlcnQtPmRhdGFfbGVuKSkgewoJCWxvZ2l0KCJVbmFibGUgdG8gcGFyc2UgWC41MDkgY2VydGlmaWNhdGUiKTsKCQlyID0gLTE7CgkJZ290byBlcnI7Cgl9CglzY19wa2NzMTVfZnJlZV9jZXJ0aWZpY2F0ZShjZXJ0KTsKCWNlcnQgPSBOVUxMOwoJcHVia2V5ID0gWDUwOV9nZXRfcHVia2V5KHg1MDkpOwoJWDUwOV9mcmVlKHg1MDkpOwoJeDUwOSA9IE5VTEw7CglpZiAocHVia2V5LT50eXBlICE9IEVWUF9QS0VZX1JTQSkgewoJCWxvZ2l0KCJQdWJsaWMga2V5IGlzIG9mIHVua25vd24gdHlwZSIpOwoJCXIgPSAtMTsKCQlnb3RvIGVycjsKCX0KCWstPnJzYSA9IEVWUF9QS0VZX2dldDFfUlNBKHB1YmtleSk7CglFVlBfUEtFWV9mcmVlKHB1YmtleSk7CgoJay0+cnNhLT5mbGFncyB8PSBSU0FfRkxBR19TSUdOX1ZFUjsKCVJTQV9zZXRfbWV0aG9kKGstPnJzYSwgc2NfZ2V0X3JzYV9tZXRob2QoKSk7Cglwcml2ID0geG1hbGxvYyhzaXplb2Yoc3RydWN0IHNjX3ByaXZfZGF0YSkpOwoJcHJpdi0+Y2VydF9pZCA9IGNpbmZvLT5pZDsKCXByaXYtPnJlZl9jb3VudCA9IDE7CglSU0Ffc2V0X2FwcF9kYXRhKGstPnJzYSwgcHJpdik7CgoJay0+ZmxhZ3MgPSBLRVlfRkxBR19FWFQ7Cgl0bXAgPSBrZXlfZmluZ2VycHJpbnQoaywgU1NIX0ZQX01ENSwgU1NIX0ZQX0hFWCk7CglkZWJ1ZygiZmluZ2VycHJpbnQgJWQgJXMiLCBrZXlfc2l6ZShrKSwgdG1wKTsKCXhmcmVlKHRtcCk7CgkKCXJldHVybiAwOwplcnI6CglpZiAoY2VydCkKCQlzY19wa2NzMTVfZnJlZV9jZXJ0aWZpY2F0ZShjZXJ0KTsKCWlmIChwdWJrZXkpCgkJRVZQX1BLRVlfZnJlZShwdWJrZXkpOwoJaWYgKHg1MDkpCgkJWDUwOV9mcmVlKHg1MDkpOwoJcmV0dXJuIHI7Cn0KCktleSAqKgpzY19nZXRfa2V5cyhjb25zdCBjaGFyICppZCwgY29uc3QgY2hhciAqcGluKQp7CglLZXkgKmssICoqa2V5czsKCWludCBpLCByLCByZWFsX2NvdW50ID0gMCwga2V5X2NvdW50OwoJc2NfcGtjczE1X2lkX3QgY2VydF9pZDsKCXNjX3BrY3MxNV9vYmplY3RfdCAqY2VydHNbMzJdOwoJY2hhciAqYnVmID0geHN0cmR1cChpZCksICpwOwoKCWRlYnVnKCJzY19nZXRfa2V5cyBjYWxsZWQ6IGlkID0gJXMiLCBpZCk7CgoJaWYgKHNjX3BpbiAhPSBOVUxMKQoJCXhmcmVlKHNjX3Bpbik7CglzY19waW4gPSAocGluID09IE5VTEwpID8gTlVMTCA6IHhzdHJkdXAocGluKTsKCgljZXJ0X2lkLmxlbiA9IDA7CglpZiAoKHAgPSBzdHJjaHIoYnVmLCAnOicpKSAhPSBOVUxMKSB7CgkJKnAgPSAwOwoJCXArKzsKCQlzY19wa2NzMTVfaGV4X3N0cmluZ190b19pZChwLCAmY2VydF9pZCk7Cgl9CglyID0gc3NjYW5mKGJ1ZiwgIiVkIiwgJnNjX3JlYWRlcl9pZCk7Cgl4ZnJlZShidWYpOwoJaWYgKHIgIT0gMSkKCQlnb3RvIGVycjsKCWlmIChwMTVjYXJkID09IE5VTEwpIHsKCQlzY19jbG9zZSgpOwoJCXIgPSBzY19pbml0KCk7CgkJaWYgKHIpIHsKCQkJZXJyb3IoIlNtYXJ0Y2FyZCBpbml0IGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCX0KCWlmIChjZXJ0X2lkLmxlbikgewoJCXIgPSBzY19wa2NzMTVfZmluZF9jZXJ0X2J5X2lkKHAxNWNhcmQsICZjZXJ0X2lkLCAmY2VydHNbMF0pOwoJCWlmIChyIDwgMCkKCQkJZ290byBlcnI7CgkJa2V5X2NvdW50ID0gMTsKCX0gZWxzZSB7CgkJciA9IHNjX3BrY3MxNV9nZXRfb2JqZWN0cyhwMTVjYXJkLCBTQ19QS0NTMTVfVFlQRV9DRVJUX1g1MDksCgkJCQkJICBjZXJ0cywgMzIpOwoJCWlmIChyID09IDApIHsKCQkJbG9naXQoIk5vIGNlcnRpZmljYXRlcyBmb3VuZCBvbiBzbWFydGNhcmQiKTsKCQkJciA9IC0xOwoJCQlnb3RvIGVycjsKCQl9IGVsc2UgaWYgKHIgPCAwKSB7CgkJCWVycm9yKCJDZXJ0aWZpY2F0ZSBlbnVtZXJhdGlvbiBmYWlsZWQ6ICVzIiwKCQkJICAgICAgc2Nfc3RyZXJyb3IocikpOwoJCQlnb3RvIGVycjsKCQl9CgkJa2V5X2NvdW50ID0gcjsKCX0KCWtleXMgPSB4bWFsbG9jKHNpemVvZihLZXkgKikgKiAoa2V5X2NvdW50KjIrMSkpOwoJZm9yIChpID0gMDsgaSA8IGtleV9jb3VudDsgaSsrKSB7CgkJc2NfcGtjczE1X29iamVjdF90ICp0bXBfb2JqID0gTlVMTDsKCQljZXJ0X2lkID0gKChzY19wa2NzMTVfY2VydF9pbmZvX3QgKikoY2VydHNbaV0tPmRhdGEpKS0+aWQ7CgkJaWYgKHNjX3BrY3MxNV9maW5kX3Bya2V5X2J5X2lkKHAxNWNhcmQsICZjZXJ0X2lkLCAmdG1wX29iaikpCgkJCS8qIHNraXAgdGhlIHB1YmxpYyBrZXkgKGNlcnRpZmljYXRlKSBpZiBubwoJCQkgKiBjb3JyZXNwb25kaW5nIHByaXZhdGUga2V5IGlzIHByZXNlbnQgKi8KCQkJY29udGludWU7CgkJayA9IGtleV9uZXcoS0VZX1JTQSk7CgkJaWYgKGsgPT0gTlVMTCkKCQkJYnJlYWs7CgkJciA9IHNjX3JlYWRfcHVia2V5KGssIGNlcnRzW2ldKTsKCQlpZiAocikgewoJCQllcnJvcigic2NfcmVhZF9wdWJrZXkgZmFpbGVkOiAlcyIsIHNjX3N0cmVycm9yKHIpKTsKCQkJa2V5X2ZyZWUoayk7CgkJCWNvbnRpbnVlOwoJCX0KCQlrZXlzW3JlYWxfY291bnRdID0gazsKCQlyZWFsX2NvdW50Kys7CgkJayA9IGtleV9uZXcoS0VZX1JTQTEpOwoJCWlmIChrID09IE5VTEwpCgkJCWJyZWFrOwoJCWNvbnZlcnRfcnNhX3RvX3JzYTEoa2V5c1tyZWFsX2NvdW50LTFdLCBrKTsKCQlrZXlzW3JlYWxfY291bnRdID0gazsKCQlyZWFsX2NvdW50Kys7Cgl9CglrZXlzW3JlYWxfY291bnRdID0gTlVMTDsKCglyZXR1cm4ga2V5czsKZXJyOgoJc2NfY2xvc2UoKTsKCXJldHVybiBOVUxMOwp9CgppbnQKc2NfcHV0X2tleShLZXkgKnBydiwgY29uc3QgY2hhciAqaWQpCnsKCWVycm9yKCJrZXkgdXBsb2FkaW5nIG5vdCB5ZXQgc3VwcG9ydGVkIik7CglyZXR1cm4gLTE7Cn0KCmNoYXIgKgpzY19nZXRfa2V5X2xhYmVsKEtleSAqa2V5KQp7CglpbnQgcjsKCWNvbnN0IHN0cnVjdCBzY19wcml2X2RhdGEgKnByaXY7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCglwcml2ID0gKGNvbnN0IHN0cnVjdCBzY19wcml2X2RhdGEgKikgUlNBX2dldF9hcHBfZGF0YShrZXktPnJzYSk7CglpZiAocHJpdiA9PSBOVUxMIHx8IHAxNWNhcmQgPT0gTlVMTCkgewoJCWxvZ2l0KCJTbWFydENhcmQga2V5IG5vdCBsb2FkZWQiKTsKCQkvKiBpbnRlcm5hbCBlcnJvciA9PiByZXR1cm4gZGVmYXVsdCBsYWJlbCAqLwoJCXJldHVybiB4c3RyZHVwKCJzbWFydGNhcmQga2V5Iik7Cgl9CglyID0gc2NfcGtjczE1X2ZpbmRfcHJrZXlfYnlfaWQocDE1Y2FyZCwgJnByaXYtPmNlcnRfaWQsICZrZXlfb2JqKTsKCWlmIChyKSB7CgkJbG9naXQoIlVuYWJsZSB0byBmaW5kIHByaXZhdGUga2V5IGZyb20gU21hcnRDYXJkOiAlcyIsCgkJICAgICAgc2Nfc3RyZXJyb3IocikpOwoJCXJldHVybiB4c3RyZHVwKCJzbWFydGNhcmQga2V5Iik7Cgl9CglpZiAoa2V5X29iaiA9PSBOVUxMIHx8IGtleV9vYmotPmxhYmVsID09IE5VTEwpCgkJLyogdGhlIG9wdGlvbmFsIFBLQ1MjMTUgbGFiZWwgZG9lcyBub3QgZXhpc3RzCgkJICogPT4gcmV0dXJuIHRoZSBkZWZhdWx0IGxhYmVsICovCgkJcmV0dXJuIHhzdHJkdXAoInNtYXJ0Y2FyZCBrZXkiKTsKCXJldHVybiB4c3RyZHVwKGtleV9vYmotPmxhYmVsKTsKfQoKI2VuZGlmIC8qIFNNQVJUQ0FSRCAqLwo=