LyoKICogQ29weXJpZ2h0IChjKSAyMDAyIEp1aGEgWXJq9mzkLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogQ29weXJpZ2h0IChjKSAyMDAxIE1hcmt1cyBGcmllZGwuCiAqIAogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTUyBPUgogKiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwKICogSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUCiAqIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GCiAqIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqLwoKI2luY2x1ZGUgImluY2x1ZGVzLmgiCiNpZiBkZWZpbmVkKFNNQVJUQ0FSRCkgJiYgZGVmaW5lZChVU0VfT1BFTlNDKQoKI2luY2x1ZGUgPG9wZW5zc2wvZXZwLmg+CiNpbmNsdWRlIDxvcGVuc3NsL3g1MDkuaD4KCiNpbmNsdWRlIDxvcGVuc2Mvb3BlbnNjLmg+CiNpbmNsdWRlIDxvcGVuc2MvcGtjczE1Lmg+CgojaW5jbHVkZSAia2V5LmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgInJlYWRwYXNzLmgiCiNpbmNsdWRlICJzY2FyZC5oIgoKI2lmIE9QRU5TU0xfVkVSU0lPTl9OVU1CRVIgPCAweDAwOTA3MDAwTCAmJiBkZWZpbmVkKENSWVBUT19MT0NLX0VOR0lORSkKI2RlZmluZSBVU0VfRU5HSU5FCiNkZWZpbmUgUlNBX2dldF9kZWZhdWx0X21ldGhvZCBSU0FfZ2V0X2RlZmF1bHRfb3BlbnNzbF9tZXRob2QKI2Vsc2UKI2VuZGlmCgojaWZkZWYgVVNFX0VOR0lORQojaW5jbHVkZSA8b3BlbnNzbC9lbmdpbmUuaD4KI2RlZmluZSBzY19nZXRfcnNhIHNjX2dldF9lbmdpbmUKI2Vsc2UKI2RlZmluZSBzY19nZXRfcnNhIHNjX2dldF9yc2FfbWV0aG9kCiNlbmRpZgoKc3RhdGljIGludCBzY19yZWFkZXJfaWQ7CnN0YXRpYyBzY19jb250ZXh0X3QgKmN0eCA9IE5VTEw7CnN0YXRpYyBzY19jYXJkX3QgKmNhcmQgPSBOVUxMOwpzdGF0aWMgc2NfcGtjczE1X2NhcmRfdCAqcDE1Y2FyZCA9IE5VTEw7CgpzdGF0aWMgY2hhciAqc2NfcGluID0gTlVMTDsKCnN0cnVjdCBzY19wcml2X2RhdGEKewoJc3RydWN0IHNjX3BrY3MxNV9pZCBjZXJ0X2lkOwoJaW50IHJlZl9jb3VudDsKfTsKCnZvaWQKc2NfY2xvc2Uodm9pZCkKewoJaWYgKHAxNWNhcmQpIHsKCQlzY19wa2NzMTVfdW5iaW5kKHAxNWNhcmQpOwoJCXAxNWNhcmQgPSBOVUxMOwoJfQoJaWYgKGNhcmQpIHsKCQlzY19kaXNjb25uZWN0X2NhcmQoY2FyZCwgMCk7CgkJY2FyZCA9IE5VTEw7Cgl9CglpZiAoY3R4KSB7CgkJc2NfcmVsZWFzZV9jb250ZXh0KGN0eCk7CgkJY3R4ID0gTlVMTDsKCX0KfQoKc3RhdGljIGludCAKc2NfaW5pdCh2b2lkKQp7CglpbnQgcjsKCglyID0gc2NfZXN0YWJsaXNoX2NvbnRleHQoJmN0eCwgIm9wZW5zc2giKTsKCWlmIChyKQoJCWdvdG8gZXJyOwoJciA9IHNjX2Nvbm5lY3RfY2FyZChjdHgtPnJlYWRlcltzY19yZWFkZXJfaWRdLCAwLCAmY2FyZCk7CglpZiAocikKCQlnb3RvIGVycjsKCXIgPSBzY19wa2NzMTVfYmluZChjYXJkLCAmcDE1Y2FyZCk7CglpZiAocikKCQlnb3RvIGVycjsKCXJldHVybiAwOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIHI7Cn0KCi8qIHByaXZhdGUga2V5IG9wZXJhdGlvbnMgKi8KCnN0YXRpYyBpbnQKc2NfcHJrZXlfb3BfaW5pdChSU0EgKnJzYSwgc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKiprZXlfb2JqX291dCkKewoJaW50IHI7CglzdHJ1Y3Qgc2NfcHJpdl9kYXRhICpwcml2OwoJc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKmtleV9vYmo7CglzdHJ1Y3Qgc2NfcGtjczE1X3Bya2V5X2luZm8gKmtleTsKCXN0cnVjdCBzY19wa2NzMTVfb2JqZWN0ICpwaW5fb2JqOwoJc3RydWN0IHNjX3BrY3MxNV9waW5faW5mbyAqcGluOwoKCXByaXYgPSAoc3RydWN0IHNjX3ByaXZfZGF0YSAqKSBSU0FfZ2V0X2FwcF9kYXRhKHJzYSk7CglpZiAocHJpdiA9PSBOVUxMKQoJCXJldHVybiAtMTsKCWlmIChwMTVjYXJkID09IE5VTEwpIHsKCQlzY19jbG9zZSgpOwoJCXIgPSBzY19pbml0KCk7CgkJaWYgKHIpIHsKCQkJZXJyb3IoIlNtYXJ0Q2FyZCBpbml0IGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCX0KCXIgPSBzY19wa2NzMTVfZmluZF9wcmtleV9ieV9pZChwMTVjYXJkLCAmcHJpdi0+Y2VydF9pZCwgJmtleV9vYmopOwoJaWYgKHIpIHsKCQllcnJvcigiVW5hYmxlIHRvIGZpbmQgcHJpdmF0ZSBrZXkgZnJvbSBTbWFydENhcmQ6ICVzIiwKCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9CglrZXkgPSBrZXlfb2JqLT5kYXRhOwoJciA9IHNjX3BrY3MxNV9maW5kX3Bpbl9ieV9hdXRoX2lkKHAxNWNhcmQsICZrZXlfb2JqLT5hdXRoX2lkLAoJCQkJCSAgJnBpbl9vYmopOwoJaWYgKHIpIHsKCQllcnJvcigiVW5hYmxlIHRvIGZpbmQgUElOIG9iamVjdCBmcm9tIFNtYXJ0Q2FyZDogJXMiLAoJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQlnb3RvIGVycjsKCX0KCXBpbiA9IHBpbl9vYmotPmRhdGE7CglyID0gc2NfbG9jayhjYXJkKTsKCWlmIChyKSB7CgkJZXJyb3IoIlVuYWJsZSB0byBsb2NrIHNtYXJ0Y2FyZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9CglpZiAoc2NfcGluICE9IE5VTEwpIHsKCQlyID0gc2NfcGtjczE1X3ZlcmlmeV9waW4ocDE1Y2FyZCwgcGluLCBzY19waW4sCgkJCQkJIHN0cmxlbihzY19waW4pKTsKCQlpZiAocikgewoJCQlzY191bmxvY2soY2FyZCk7CgkJCWVycm9yKCJQSU4gY29kZSB2ZXJpZmljYXRpb24gZmFpbGVkOiAlcyIsCgkJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQkJZ290byBlcnI7CgkJfQoJfQoJKmtleV9vYmpfb3V0ID0ga2V5X29iajsKCXJldHVybiAwOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50CnNjX3ByaXZhdGVfZGVjcnlwdChpbnQgZmxlbiwgdV9jaGFyICpmcm9tLCB1X2NoYXIgKnRvLCBSU0EgKnJzYSwKICAgIGludCBwYWRkaW5nKQp7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCWludCByOwoKCWlmIChwYWRkaW5nICE9IFJTQV9QS0NTMV9QQURESU5HKQoJCXJldHVybiAtMTsJCglyID0gc2NfcHJrZXlfb3BfaW5pdChyc2EsICZrZXlfb2JqKTsKCWlmIChyKQoJCXJldHVybiAtMTsKCXIgPSBzY19wa2NzMTVfZGVjaXBoZXIocDE1Y2FyZCwga2V5X29iaiwgMCwgZnJvbSwgZmxlbiwgdG8sIGZsZW4pOwoJc2NfdW5sb2NrKGNhcmQpOwoJaWYgKHIgPCAwKSB7CgkJZXJyb3IoInNjX3BrY3MxNV9kZWNpcGhlcigpIGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9CglyZXR1cm4gcjsKZXJyOgoJc2NfY2xvc2UoKTsKCXJldHVybiAtMTsKfQoKc3RhdGljIGludApzY19zaWduKGludCB0eXBlLCB1X2NoYXIgKm0sIHVuc2lnbmVkIGludCBtX2xlbiwKCXVuc2lnbmVkIGNoYXIgKnNpZ3JldCwgdW5zaWduZWQgaW50ICpzaWdsZW4sIFJTQSAqcnNhKQp7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCWludCByOwoJdW5zaWduZWQgbG9uZyBmbGFncyA9IDA7CgoJciA9IHNjX3Bya2V5X29wX2luaXQocnNhLCAma2V5X29iaik7CglpZiAocikKCQlyZXR1cm4gLTE7CgkvKiBGSVhNRTogbGVuZ3RoIG9mIHNpZ3JldCBjb3JyZWN0PyAqLwoJLyogRklYTUU6IGNoZWNrICd0eXBlJyBhbmQgbW9kaWZ5IGZsYWdzIGFjY29yZGluZ2x5ICovCglmbGFncyA9IFNDX0FMR09SSVRITV9SU0FfUEFEX1BLQ1MxIHwgU0NfQUxHT1JJVEhNX1JTQV9IQVNIX1NIQTE7CglyID0gc2NfcGtjczE1X2NvbXB1dGVfc2lnbmF0dXJlKHAxNWNhcmQsIGtleV9vYmosIGZsYWdzLAoJCQkJCW0sIG1fbGVuLCBzaWdyZXQsIFJTQV9zaXplKHJzYSkpOwoJc2NfdW5sb2NrKGNhcmQpOwoJaWYgKHIgPCAwKSB7CgkJZXJyb3IoInNjX3BrY3MxNV9jb21wdXRlX3NpZ25hdHVyZSgpIGZhaWxlZDogJXMiLAoJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQlnb3RvIGVycjsKCX0KCSpzaWdsZW4gPSByOwoJcmV0dXJuIDE7CmVycjoKCXNjX2Nsb3NlKCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludApzY19wcml2YXRlX2VuY3J5cHQoaW50IGZsZW4sIHVfY2hhciAqZnJvbSwgdV9jaGFyICp0bywgUlNBICpyc2EsCiAgICBpbnQgcGFkZGluZykKewoJZXJyb3IoIlByaXZhdGUga2V5IGVuY3J5cHRpb24gbm90IHN1cHBvcnRlZCIpOwoJcmV0dXJuIC0xOwp9CgovKiBjYWxsZWQgb24gZnJlZSAqLwoKc3RhdGljIGludCAoKm9yaWdfZmluaXNoKShSU0EgKnJzYSkgPSBOVUxMOwoKc3RhdGljIGludApzY19maW5pc2goUlNBICpyc2EpCnsKCXN0cnVjdCBzY19wcml2X2RhdGEgKnByaXY7CgoJcHJpdiA9IFJTQV9nZXRfYXBwX2RhdGEocnNhKTsKCXByaXYtPnJlZl9jb3VudC0tOwoJaWYgKHByaXYtPnJlZl9jb3VudCA9PSAwKSB7CgkJZnJlZShwcml2KTsKCQlzY19jbG9zZSgpOwoJfQoJaWYgKG9yaWdfZmluaXNoKQoJCW9yaWdfZmluaXNoKHJzYSk7CglyZXR1cm4gMTsKfQoKLyogZW5naW5lIGZvciBvdmVybG9hZGluZyBwcml2YXRlIGtleSBvcGVyYXRpb25zICovCgpzdGF0aWMgUlNBX01FVEhPRCAqCnNjX2dldF9yc2FfbWV0aG9kKHZvaWQpCnsKCXN0YXRpYyBSU0FfTUVUSE9EIHNtYXJ0X3JzYTsKCWNvbnN0IFJTQV9NRVRIT0QgKmRlZiA9IFJTQV9nZXRfZGVmYXVsdF9tZXRob2QoKTsKCgkvKiB1c2UgdGhlIE9wZW5TU0wgdmVyc2lvbiAqLwoJbWVtY3B5KCZzbWFydF9yc2EsIGRlZiwgc2l6ZW9mKHNtYXJ0X3JzYSkpOwoKCXNtYXJ0X3JzYS5uYW1lCQk9ICJvcGVuc2MiOwoKCS8qIG92ZXJsb2FkICovCglzbWFydF9yc2EucnNhX3ByaXZfZW5jCT0gc2NfcHJpdmF0ZV9lbmNyeXB0OwoJc21hcnRfcnNhLnJzYV9wcml2X2RlYwk9IHNjX3ByaXZhdGVfZGVjcnlwdDsKCXNtYXJ0X3JzYS5yc2Ffc2lnbgk9IHNjX3NpZ247CgoJLyogc2F2ZSBvcmlnaW5hbCAqLwoJb3JpZ19maW5pc2gJCT0gZGVmLT5maW5pc2g7CglzbWFydF9yc2EuZmluaXNoCT0gc2NfZmluaXNoOwoKCXJldHVybiAmc21hcnRfcnNhOwp9CgojaWZkZWYgVVNFX0VOR0lORQpzdGF0aWMgRU5HSU5FICoKc2NfZ2V0X2VuZ2luZSh2b2lkKQp7CglzdGF0aWMgRU5HSU5FICpzbWFydF9lbmdpbmUgPSBOVUxMOwoKCWlmICgoc21hcnRfZW5naW5lID0gRU5HSU5FX25ldygpKSA9PSBOVUxMKQoJCWZhdGFsKCJFTkdJTkVfbmV3IGZhaWxlZCIpOwoKCUVOR0lORV9zZXRfaWQoc21hcnRfZW5naW5lLCAib3BlbnNjIik7CglFTkdJTkVfc2V0X25hbWUoc21hcnRfZW5naW5lLCAiT3BlblNDIik7CgoJRU5HSU5FX3NldF9SU0Eoc21hcnRfZW5naW5lLCBzY19nZXRfcnNhX21ldGhvZCgpKTsKCUVOR0lORV9zZXRfRFNBKHNtYXJ0X2VuZ2luZSwgRFNBX2dldF9kZWZhdWx0X29wZW5zc2xfbWV0aG9kKCkpOwoJRU5HSU5FX3NldF9ESChzbWFydF9lbmdpbmUsIERIX2dldF9kZWZhdWx0X29wZW5zc2xfbWV0aG9kKCkpOwoJRU5HSU5FX3NldF9SQU5EKHNtYXJ0X2VuZ2luZSwgUkFORF9TU0xlYXkoKSk7CglFTkdJTkVfc2V0X0JOX21vZF9leHAoc21hcnRfZW5naW5lLCBCTl9tb2RfZXhwKTsKCglyZXR1cm4gc21hcnRfZW5naW5lOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQKY29udmVydF9yc2FfdG9fcnNhMShLZXkgKiBpbiwgS2V5ICogb3V0KQp7CglzdHJ1Y3Qgc2NfcHJpdl9kYXRhICpwcml2OwoJCglvdXQtPnJzYS0+ZmxhZ3MgPSBpbi0+cnNhLT5mbGFnczsKCW91dC0+ZmxhZ3MgPSBpbi0+ZmxhZ3M7CglSU0Ffc2V0X21ldGhvZChvdXQtPnJzYSwgUlNBX2dldF9tZXRob2QoaW4tPnJzYSkpOwoJQk5fY29weShvdXQtPnJzYS0+biwgaW4tPnJzYS0+bik7CglCTl9jb3B5KG91dC0+cnNhLT5lLCBpbi0+cnNhLT5lKTsKCXByaXYgPSBSU0FfZ2V0X2FwcF9kYXRhKGluLT5yc2EpOwoJcHJpdi0+cmVmX2NvdW50Kys7CglSU0Ffc2V0X2FwcF9kYXRhKG91dC0+cnNhLCBwcml2KTsKCXJldHVybjsKfQoKc3RhdGljIGludCAKc2NfcmVhZF9wdWJrZXkoS2V5ICogaywgY29uc3Qgc3RydWN0IHNjX3BrY3MxNV9vYmplY3QgKmNlcnRfb2JqKQp7CglpbnQgcjsKCXNjX3BrY3MxNV9jZXJ0X3QgKmNlcnQgPSBOVUxMOwoJc3RydWN0IHNjX3ByaXZfZGF0YSAqcHJpdiA9IE5VTEw7CglzY19wa2NzMTVfY2VydF9pbmZvX3QgKmNpbmZvID0gY2VydF9vYmotPmRhdGE7CgoJWDUwOSAqeDUwOSA9IE5VTEw7CglFVlBfUEtFWSAqcHVia2V5ID0gTlVMTDsKCXU4ICpwOwoJY2hhciAqdG1wOwoJCglkZWJ1Zygic2NfcmVhZF9wdWJrZXkoKSB3aXRoIGNlcnQgaWQgJTAyWCIsIGNpbmZvLT5pZC52YWx1ZVswXSk7CglyID0gc2NfcGtjczE1X3JlYWRfY2VydGlmaWNhdGUocDE1Y2FyZCwgY2luZm8sICZjZXJ0KTsKCWlmIChyKSB7CgkJbG9nKCJDZXJ0aWZpY2F0ZSByZWFkIGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9Cgl4NTA5ID0gWDUwOV9uZXcoKTsKCWlmICh4NTA5ID09IE5VTEwpIHsKCQlyID0gLTE7IAoJCWdvdG8gZXJyOwoJfQoJcCA9IGNlcnQtPmRhdGE7CglpZiAoIWQyaV9YNTA5KCZ4NTA5LCAmcCwgY2VydC0+ZGF0YV9sZW4pKSB7CgkJbG9nKCJVbmFibGUgdG8gcGFyc2UgWC41MDkgY2VydGlmaWNhdGUiKTsKCQlyID0gLTE7CgkJZ290byBlcnI7Cgl9CglzY19wa2NzMTVfZnJlZV9jZXJ0aWZpY2F0ZShjZXJ0KTsKCWNlcnQgPSBOVUxMOwoJcHVia2V5ID0gWDUwOV9nZXRfcHVia2V5KHg1MDkpOwoJWDUwOV9mcmVlKHg1MDkpOwoJeDUwOSA9IE5VTEw7CglpZiAocHVia2V5LT50eXBlICE9IEVWUF9QS0VZX1JTQSkgewoJCWxvZygiUHVibGljIGtleSBpcyBvZiB1bmtub3duIHR5cGUiKTsKCQlyID0gLTE7CgkJZ290byBlcnI7Cgl9CglrLT5yc2EgPSBFVlBfUEtFWV9nZXQxX1JTQShwdWJrZXkpOwoJRVZQX1BLRVlfZnJlZShwdWJrZXkpOwoKCWstPnJzYS0+ZmxhZ3MgfD0gUlNBX0ZMQUdfU0lHTl9WRVI7CglSU0Ffc2V0X21ldGhvZChrLT5yc2EsIHNjX2dldF9yc2FfbWV0aG9kKCkpOwoJcHJpdiA9IHhtYWxsb2Moc2l6ZW9mKHN0cnVjdCBzY19wcml2X2RhdGEpKTsKCXByaXYtPmNlcnRfaWQgPSBjaW5mby0+aWQ7Cglwcml2LT5yZWZfY291bnQgPSAxOwoJUlNBX3NldF9hcHBfZGF0YShrLT5yc2EsIHByaXYpOwoKCWstPmZsYWdzID0gS0VZX0ZMQUdfRVhUOwoJdG1wID0ga2V5X2ZpbmdlcnByaW50KGssIFNTSF9GUF9NRDUsIFNTSF9GUF9IRVgpOwoJZGVidWcoImZpbmdlcnByaW50ICVkICVzIiwga2V5X3NpemUoayksIHRtcCk7Cgl4ZnJlZSh0bXApOwoJCglyZXR1cm4gMDsKZXJyOgoJaWYgKGNlcnQpCgkJc2NfcGtjczE1X2ZyZWVfY2VydGlmaWNhdGUoY2VydCk7CglpZiAocHVia2V5KQoJCUVWUF9QS0VZX2ZyZWUocHVia2V5KTsKCWlmICh4NTA5KQoJCVg1MDlfZnJlZSh4NTA5KTsKCXJldHVybiByOwp9CgpLZXkgKioKc2NfZ2V0X2tleXMoY29uc3QgY2hhciAqaWQsIGNvbnN0IGNoYXIgKnBpbikKewoJS2V5ICprLCAqKmtleXM7CglpbnQgaSwgciwgcmVhbF9jb3VudCA9IDAsIGtleV9jb3VudDsKCXNjX3BrY3MxNV9pZF90IGNlcnRfaWQ7CglzY19wa2NzMTVfb2JqZWN0X3QgKmNlcnRzWzMyXTsKCWNoYXIgKmJ1ZiA9IHhzdHJkdXAoaWQpLCAqcDsKCglkZWJ1Zygic2NfZ2V0X2tleXMgY2FsbGVkOiBpZCA9ICVzIiwgaWQpOwoKCWlmIChzY19waW4gIT0gTlVMTCkKCQl4ZnJlZShzY19waW4pOwoJc2NfcGluID0gKHBpbiA9PSBOVUxMKSA/IE5VTEwgOiB4c3RyZHVwKHBpbik7CgoJY2VydF9pZC5sZW4gPSAwOwoJaWYgKChwID0gc3RyY2hyKGJ1ZiwgJzonKSkgIT0gTlVMTCkgewoJCSpwID0gMDsKCQlwKys7CgkJc2NfcGtjczE1X2hleF9zdHJpbmdfdG9faWQocCwgJmNlcnRfaWQpOwoJfQoJciA9IHNzY2FuZihidWYsICIlZCIsICZzY19yZWFkZXJfaWQpOwoJeGZyZWUoYnVmKTsKCWlmIChyICE9IDEpCgkJZ290byBlcnI7CglpZiAocDE1Y2FyZCA9PSBOVUxMKSB7CgkJc2NfY2xvc2UoKTsKCQlyID0gc2NfaW5pdCgpOwoJCWlmIChyKSB7CgkJCWVycm9yKCJTbWFydGNhcmQgaW5pdCBmYWlsZWQ6ICVzIiwgc2Nfc3RyZXJyb3IocikpOwoJCQlnb3RvIGVycjsKCQl9Cgl9CglpZiAoY2VydF9pZC5sZW4pIHsKCQlyID0gc2NfcGtjczE1X2ZpbmRfY2VydF9ieV9pZChwMTVjYXJkLCAmY2VydF9pZCwgJmNlcnRzWzBdKTsKCQlpZiAociA8IDApCgkJCWdvdG8gZXJyOwoJCWtleV9jb3VudCA9IDE7Cgl9IGVsc2UgewoJCXIgPSBzY19wa2NzMTVfZ2V0X29iamVjdHMocDE1Y2FyZCwgU0NfUEtDUzE1X1RZUEVfQ0VSVF9YNTA5LAoJCQkJCSAgY2VydHMsIDMyKTsKCQlpZiAociA9PSAwKSB7CgkJCWxvZygiTm8gY2VydGlmaWNhdGVzIGZvdW5kIG9uIHNtYXJ0Y2FyZCIpOwoJCQlyID0gLTE7CgkJCWdvdG8gZXJyOwoJCX0gZWxzZSBpZiAociA8IDApIHsKCQkJZXJyb3IoIkNlcnRpZmljYXRlIGVudW1lcmF0aW9uIGZhaWxlZDogJXMiLAoJCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCQlrZXlfY291bnQgPSByOwoJfQoJLyogRklYTUU6IG9ubHkga2VlcCBlbnRyaWVzIHdpdGggYSBjb3JyZXNwb25kaW5nIHByaXZhdGUga2V5ICovCglrZXlzID0geG1hbGxvYyhzaXplb2YoS2V5ICopICogKGtleV9jb3VudCoyKzEpKTsKCWZvciAoaSA9IDA7IGkgPCBrZXlfY291bnQ7IGkrKykgewoJCWsgPSBrZXlfbmV3KEtFWV9SU0EpOwoJCWlmIChrID09IE5VTEwpCgkJCWJyZWFrOwoJCXIgPSBzY19yZWFkX3B1YmtleShrLCBjZXJ0c1tpXSk7CgkJaWYgKHIpIHsKCQkJZXJyb3IoInNjX3JlYWRfcHVia2V5IGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJCWtleV9mcmVlKGspOwoJCQljb250aW51ZTsKCQl9CgkJa2V5c1tyZWFsX2NvdW50XSA9IGs7CgkJcmVhbF9jb3VudCsrOwoJCWsgPSBrZXlfbmV3KEtFWV9SU0ExKTsKCQlpZiAoayA9PSBOVUxMKQoJCQlicmVhazsKCQljb252ZXJ0X3JzYV90b19yc2ExKGtleXNbcmVhbF9jb3VudC0xXSwgayk7CgkJa2V5c1tyZWFsX2NvdW50XSA9IGs7CgkJcmVhbF9jb3VudCsrOwoJfQoJa2V5c1tyZWFsX2NvdW50XSA9IE5VTEw7CgoJcmV0dXJuIGtleXM7CmVycjoKCXNjX2Nsb3NlKCk7CglyZXR1cm4gTlVMTDsKfQoKaW50CnNjX3B1dF9rZXkoS2V5ICpwcnYsIGNvbnN0IGNoYXIgKmlkKQp7CgllcnJvcigia2V5IHVwbG9hZGluZyBub3QgeWV0IHN1cHBvcnRlZCIpOwoJcmV0dXJuIC0xOwp9CgojZW5kaWYgLyogU01BUlRDQVJEICovCg==