LyoKICogQ29weXJpZ2h0IChjKSAyMDAyIEp1aGEgWXJq9mzkLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogQ29weXJpZ2h0IChjKSAyMDAxIE1hcmt1cyBGcmllZGwuCiAqCiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKICogYXJlIG1ldDoKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAogKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCiAqICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIEFVVEhPUiBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTIE9SCiAqIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4KICogSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULAogKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQKICogTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAogKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YKICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KICovCgojaW5jbHVkZSAiaW5jbHVkZXMuaCIKI2lmIGRlZmluZWQoU01BUlRDQVJEKSAmJiBkZWZpbmVkKFVTRV9PUEVOU0MpCgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CgojaW5jbHVkZSA8b3BlbnNzbC9ldnAuaD4KI2luY2x1ZGUgPG9wZW5zc2wveDUwOS5oPgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2luY2x1ZGUgPG9wZW5zYy9vcGVuc2MuaD4KI2luY2x1ZGUgPG9wZW5zYy9wa2NzMTUuaD4KCiNpbmNsdWRlICJrZXkuaCIKI2luY2x1ZGUgImxvZy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgojaW5jbHVkZSAibWlzYy5oIgojaW5jbHVkZSAic2NhcmQuaCIKCiNpZiBPUEVOU1NMX1ZFUlNJT05fTlVNQkVSIDwgMHgwMDkwNzAwMEwgJiYgZGVmaW5lZChDUllQVE9fTE9DS19FTkdJTkUpCiNkZWZpbmUgVVNFX0VOR0lORQojZGVmaW5lIFJTQV9nZXRfZGVmYXVsdF9tZXRob2QgUlNBX2dldF9kZWZhdWx0X29wZW5zc2xfbWV0aG9kCiNlbHNlCiNlbmRpZgoKI2lmZGVmIFVTRV9FTkdJTkUKI2luY2x1ZGUgPG9wZW5zc2wvZW5naW5lLmg+CiNkZWZpbmUgc2NfZ2V0X3JzYSBzY19nZXRfZW5naW5lCiNlbHNlCiNkZWZpbmUgc2NfZ2V0X3JzYSBzY19nZXRfcnNhX21ldGhvZAojZW5kaWYKCnN0YXRpYyBpbnQgc2NfcmVhZGVyX2lkOwpzdGF0aWMgc2NfY29udGV4dF90ICpjdHggPSBOVUxMOwpzdGF0aWMgc2NfY2FyZF90ICpjYXJkID0gTlVMTDsKc3RhdGljIHNjX3BrY3MxNV9jYXJkX3QgKnAxNWNhcmQgPSBOVUxMOwoKc3RhdGljIGNoYXIgKnNjX3BpbiA9IE5VTEw7CgpzdHJ1Y3Qgc2NfcHJpdl9kYXRhCnsKCXN0cnVjdCBzY19wa2NzMTVfaWQgY2VydF9pZDsKCWludCByZWZfY291bnQ7Cn07Cgp2b2lkCnNjX2Nsb3NlKHZvaWQpCnsKCWlmIChwMTVjYXJkKSB7CgkJc2NfcGtjczE1X3VuYmluZChwMTVjYXJkKTsKCQlwMTVjYXJkID0gTlVMTDsKCX0KCWlmIChjYXJkKSB7CgkJc2NfZGlzY29ubmVjdF9jYXJkKGNhcmQsIDApOwoJCWNhcmQgPSBOVUxMOwoJfQoJaWYgKGN0eCkgewoJCXNjX3JlbGVhc2VfY29udGV4dChjdHgpOwoJCWN0eCA9IE5VTEw7Cgl9Cn0KCnN0YXRpYyBpbnQKc2NfaW5pdCh2b2lkKQp7CglpbnQgcjsKCglyID0gc2NfZXN0YWJsaXNoX2NvbnRleHQoJmN0eCwgIm9wZW5zc2giKTsKCWlmIChyKQoJCWdvdG8gZXJyOwoJaWYgKHNjX3JlYWRlcl9pZCA+PSBjdHgtPnJlYWRlcl9jb3VudCkgewoJCXIgPSBTQ19FUlJPUl9OT19SRUFERVJTX0ZPVU5EOwoJCWVycm9yKCJJbGxlZ2FsIHJlYWRlciBudW1iZXIgJWQgKG1heCAlZCkiLCBzY19yZWFkZXJfaWQsCgkJICAgIGN0eC0+cmVhZGVyX2NvdW50IC0xKTsKCQlnb3RvIGVycjsKCX0KCXIgPSBzY19jb25uZWN0X2NhcmQoY3R4LT5yZWFkZXJbc2NfcmVhZGVyX2lkXSwgMCwgJmNhcmQpOwoJaWYgKHIpCgkJZ290byBlcnI7CglyID0gc2NfcGtjczE1X2JpbmQoY2FyZCwgJnAxNWNhcmQpOwoJaWYgKHIpCgkJZ290byBlcnI7CglyZXR1cm4gMDsKZXJyOgoJc2NfY2xvc2UoKTsKCXJldHVybiByOwp9CgovKiBwcml2YXRlIGtleSBvcGVyYXRpb25zICovCgpzdGF0aWMgaW50CnNjX3Bya2V5X29wX2luaXQoUlNBICpyc2EsIHN0cnVjdCBzY19wa2NzMTVfb2JqZWN0ICoqa2V5X29ial9vdXQsCgl1bnNpZ25lZCBpbnQgdXNhZ2UpCnsKCWludCByOwoJc3RydWN0IHNjX3ByaXZfZGF0YSAqcHJpdjsKCXN0cnVjdCBzY19wa2NzMTVfb2JqZWN0ICprZXlfb2JqOwoJc3RydWN0IHNjX3BrY3MxNV9wcmtleV9pbmZvICprZXk7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqcGluX29iajsKCXN0cnVjdCBzY19wa2NzMTVfcGluX2luZm8gKnBpbjsKCglwcml2ID0gKHN0cnVjdCBzY19wcml2X2RhdGEgKikgUlNBX2dldF9hcHBfZGF0YShyc2EpOwoJaWYgKHByaXYgPT0gTlVMTCkKCQlyZXR1cm4gLTE7CglpZiAocDE1Y2FyZCA9PSBOVUxMKSB7CgkJc2NfY2xvc2UoKTsKCQlyID0gc2NfaW5pdCgpOwoJCWlmIChyKSB7CgkJCWVycm9yKCJTbWFydENhcmQgaW5pdCBmYWlsZWQ6ICVzIiwgc2Nfc3RyZXJyb3IocikpOwoJCQlnb3RvIGVycjsKCQl9Cgl9CglyID0gc2NfcGtjczE1X2ZpbmRfcHJrZXlfYnlfaWRfdXNhZ2UocDE1Y2FyZCwgJnByaXYtPmNlcnRfaWQsCgkJdXNhZ2UsICZrZXlfb2JqKTsKCWlmIChyKSB7CgkJZXJyb3IoIlVuYWJsZSB0byBmaW5kIHByaXZhdGUga2V5IGZyb20gU21hcnRDYXJkOiAlcyIsCgkJICAgICAgc2Nfc3RyZXJyb3IocikpOwoJCWdvdG8gZXJyOwoJfQoJa2V5ID0ga2V5X29iai0+ZGF0YTsKCXIgPSBzY19wa2NzMTVfZmluZF9waW5fYnlfYXV0aF9pZChwMTVjYXJkLCAma2V5X29iai0+YXV0aF9pZCwKCQkJCQkgICZwaW5fb2JqKTsKCWlmIChyID09IFNDX0VSUk9SX09CSkVDVF9OT1RfRk9VTkQpIHsKCQkvKiBubyBwaW4gcmVxdWlyZWQgKi8KCQlyID0gc2NfbG9jayhjYXJkKTsKCQlpZiAocikgewoJCQllcnJvcigiVW5hYmxlIHRvIGxvY2sgc21hcnRjYXJkOiAlcyIsIHNjX3N0cmVycm9yKHIpKTsKCQkJZ290byBlcnI7CgkJfQoJCSprZXlfb2JqX291dCA9IGtleV9vYmo7CgkJcmV0dXJuIDA7Cgl9IGVsc2UgaWYgKHIpIHsKCQllcnJvcigiVW5hYmxlIHRvIGZpbmQgUElOIG9iamVjdCBmcm9tIFNtYXJ0Q2FyZDogJXMiLAoJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQlnb3RvIGVycjsKCX0KCXBpbiA9IHBpbl9vYmotPmRhdGE7CglyID0gc2NfbG9jayhjYXJkKTsKCWlmIChyKSB7CgkJZXJyb3IoIlVuYWJsZSB0byBsb2NrIHNtYXJ0Y2FyZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9CglpZiAoc2NfcGluICE9IE5VTEwpIHsKCQlyID0gc2NfcGtjczE1X3ZlcmlmeV9waW4ocDE1Y2FyZCwgcGluLCBzY19waW4sCgkJCQkJIHN0cmxlbihzY19waW4pKTsKCQlpZiAocikgewoJCQlzY191bmxvY2soY2FyZCk7CgkJCWVycm9yKCJQSU4gY29kZSB2ZXJpZmljYXRpb24gZmFpbGVkOiAlcyIsCgkJCSAgICAgIHNjX3N0cmVycm9yKHIpKTsKCQkJZ290byBlcnI7CgkJfQoJfQoJKmtleV9vYmpfb3V0ID0ga2V5X29iajsKCXJldHVybiAwOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIC0xOwp9CgojZGVmaW5lIFNDX1VTQUdFX0RFQ1JZUFQJU0NfUEtDUzE1X1BSS0VZX1VTQUdFX0RFQ1JZUFQgfCBcCgkJCQlTQ19QS0NTMTVfUFJLRVlfVVNBR0VfVU5XUkFQCgpzdGF0aWMgaW50CnNjX3ByaXZhdGVfZGVjcnlwdChpbnQgZmxlbiwgdV9jaGFyICpmcm9tLCB1X2NoYXIgKnRvLCBSU0EgKnJzYSwKICAgIGludCBwYWRkaW5nKQp7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCWludCByOwoKCWlmIChwYWRkaW5nICE9IFJTQV9QS0NTMV9QQURESU5HKQoJCXJldHVybiAtMTsKCXIgPSBzY19wcmtleV9vcF9pbml0KHJzYSwgJmtleV9vYmosIFNDX1VTQUdFX0RFQ1JZUFQpOwoJaWYgKHIpCgkJcmV0dXJuIC0xOwoJciA9IHNjX3BrY3MxNV9kZWNpcGhlcihwMTVjYXJkLCBrZXlfb2JqLCBTQ19BTEdPUklUSE1fUlNBX1BBRF9QS0NTMSwKCSAgICBmcm9tLCBmbGVuLCB0bywgZmxlbik7CglzY191bmxvY2soY2FyZCk7CglpZiAociA8IDApIHsKCQllcnJvcigic2NfcGtjczE1X2RlY2lwaGVyKCkgZmFpbGVkOiAlcyIsIHNjX3N0cmVycm9yKHIpKTsKCQlnb3RvIGVycjsKCX0KCXJldHVybiByOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIC0xOwp9CgojZGVmaW5lIFNDX1VTQUdFX1NJR04gCQlTQ19QS0NTMTVfUFJLRVlfVVNBR0VfU0lHTiB8IFwKCQkJCVNDX1BLQ1MxNV9QUktFWV9VU0FHRV9TSUdOUkVDT1ZFUgoKc3RhdGljIGludApzY19zaWduKGludCB0eXBlLCB1X2NoYXIgKm0sIHVuc2lnbmVkIGludCBtX2xlbiwKCXVuc2lnbmVkIGNoYXIgKnNpZ3JldCwgdW5zaWduZWQgaW50ICpzaWdsZW4sIFJTQSAqcnNhKQp7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCWludCByOwoJdW5zaWduZWQgbG9uZyBmbGFncyA9IDA7CgoJLyogWFhYOiBzY19wcmtleV9vcF9pbml0IHdpbGwgc2VhcmNoIGZvciBhIHBrY3MxNSBwcml2YXRlCgkgKiBrZXkgb2JqZWN0IHdpdGggdGhlIHNpZ24gb3Igc2lnbnJlY292ZXIgdXNhZ2UgZmxhZyBzZXQuCgkgKiBJZiB0aGUgc2lnbmluZyBrZXkgaGFzIG9ubHkgdGhlIG5vbi1yZXB1ZGlhdGlvbiBmbGFnIHNldAoJICogdGhlIGtleSB3aWxsIGJlIHJlamVjdGVkIGFzIHVzaW5nIGEgbm9uLXJlcHVkaWF0aW9uIGtleQoJICogZm9yIGF1dGhlbnRpY2F0aW9uIGlzIG5vdCByZWNvbW1lbmRlZC4gTm90ZTogVGhpcyBkb2VzIG5vdAoJICogcHJldmVudCB0aGUgdXNlIG9mIGEgbm9uLXJlcHVkaWF0aW9uIGtleSBmb3IgYXV0aGVudGljYXRpb24KCSAqIGlmIHRoZSBzaWduIG9yIHNpZ25yZWNvdmVyIGZsYWcgaXMgc2V0IGFzIHdlbGwuCgkgKi8KCXIgPSBzY19wcmtleV9vcF9pbml0KHJzYSwgJmtleV9vYmosIFNDX1VTQUdFX1NJR04pOwoJaWYgKHIpCgkJcmV0dXJuIC0xOwoJLyogRklYTUU6IGxlbmd0aCBvZiBzaWdyZXQgY29ycmVjdD8gKi8KCS8qIEZJWE1FOiBjaGVjayAndHlwZScgYW5kIG1vZGlmeSBmbGFncyBhY2NvcmRpbmdseSAqLwoJZmxhZ3MgPSBTQ19BTEdPUklUSE1fUlNBX1BBRF9QS0NTMSB8IFNDX0FMR09SSVRITV9SU0FfSEFTSF9TSEExOwoJciA9IHNjX3BrY3MxNV9jb21wdXRlX3NpZ25hdHVyZShwMTVjYXJkLCBrZXlfb2JqLCBmbGFncywKCQkJCQltLCBtX2xlbiwgc2lncmV0LCBSU0Ffc2l6ZShyc2EpKTsKCXNjX3VubG9jayhjYXJkKTsKCWlmIChyIDwgMCkgewoJCWVycm9yKCJzY19wa2NzMTVfY29tcHV0ZV9zaWduYXR1cmUoKSBmYWlsZWQ6ICVzIiwKCQkgICAgICBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9Cgkqc2lnbGVuID0gcjsKCXJldHVybiAxOwplcnI6CglzY19jbG9zZSgpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKc2NfcHJpdmF0ZV9lbmNyeXB0KGludCBmbGVuLCB1X2NoYXIgKmZyb20sIHVfY2hhciAqdG8sIFJTQSAqcnNhLAogICAgaW50IHBhZGRpbmcpCnsKCWVycm9yKCJQcml2YXRlIGtleSBlbmNyeXB0aW9uIG5vdCBzdXBwb3J0ZWQiKTsKCXJldHVybiAtMTsKfQoKLyogY2FsbGVkIG9uIGZyZWUgKi8KCnN0YXRpYyBpbnQgKCpvcmlnX2ZpbmlzaCkoUlNBICpyc2EpID0gTlVMTDsKCnN0YXRpYyBpbnQKc2NfZmluaXNoKFJTQSAqcnNhKQp7CglzdHJ1Y3Qgc2NfcHJpdl9kYXRhICpwcml2OwoKCXByaXYgPSBSU0FfZ2V0X2FwcF9kYXRhKHJzYSk7Cglwcml2LT5yZWZfY291bnQtLTsKCWlmIChwcml2LT5yZWZfY291bnQgPT0gMCkgewoJCWZyZWUocHJpdik7CgkJc2NfY2xvc2UoKTsKCX0KCWlmIChvcmlnX2ZpbmlzaCkKCQlvcmlnX2ZpbmlzaChyc2EpOwoJcmV0dXJuIDE7Cn0KCi8qIGVuZ2luZSBmb3Igb3ZlcmxvYWRpbmcgcHJpdmF0ZSBrZXkgb3BlcmF0aW9ucyAqLwoKc3RhdGljIFJTQV9NRVRIT0QgKgpzY19nZXRfcnNhX21ldGhvZCh2b2lkKQp7CglzdGF0aWMgUlNBX01FVEhPRCBzbWFydF9yc2E7Cgljb25zdCBSU0FfTUVUSE9EICpkZWYgPSBSU0FfZ2V0X2RlZmF1bHRfbWV0aG9kKCk7CgoJLyogdXNlIHRoZSBPcGVuU1NMIHZlcnNpb24gKi8KCW1lbWNweSgmc21hcnRfcnNhLCBkZWYsIHNpemVvZihzbWFydF9yc2EpKTsKCglzbWFydF9yc2EubmFtZQkJPSAib3BlbnNjIjsKCgkvKiBvdmVybG9hZCAqLwoJc21hcnRfcnNhLnJzYV9wcml2X2VuYwk9IHNjX3ByaXZhdGVfZW5jcnlwdDsKCXNtYXJ0X3JzYS5yc2FfcHJpdl9kZWMJPSBzY19wcml2YXRlX2RlY3J5cHQ7CglzbWFydF9yc2EucnNhX3NpZ24JPSBzY19zaWduOwoKCS8qIHNhdmUgb3JpZ2luYWwgKi8KCW9yaWdfZmluaXNoCQk9IGRlZi0+ZmluaXNoOwoJc21hcnRfcnNhLmZpbmlzaAk9IHNjX2ZpbmlzaDsKCglyZXR1cm4gJnNtYXJ0X3JzYTsKfQoKI2lmZGVmIFVTRV9FTkdJTkUKc3RhdGljIEVOR0lORSAqCnNjX2dldF9lbmdpbmUodm9pZCkKewoJc3RhdGljIEVOR0lORSAqc21hcnRfZW5naW5lID0gTlVMTDsKCglpZiAoKHNtYXJ0X2VuZ2luZSA9IEVOR0lORV9uZXcoKSkgPT0gTlVMTCkKCQlmYXRhbCgiRU5HSU5FX25ldyBmYWlsZWQiKTsKCglFTkdJTkVfc2V0X2lkKHNtYXJ0X2VuZ2luZSwgIm9wZW5zYyIpOwoJRU5HSU5FX3NldF9uYW1lKHNtYXJ0X2VuZ2luZSwgIk9wZW5TQyIpOwoKCUVOR0lORV9zZXRfUlNBKHNtYXJ0X2VuZ2luZSwgc2NfZ2V0X3JzYV9tZXRob2QoKSk7CglFTkdJTkVfc2V0X0RTQShzbWFydF9lbmdpbmUsIERTQV9nZXRfZGVmYXVsdF9vcGVuc3NsX21ldGhvZCgpKTsKCUVOR0lORV9zZXRfREgoc21hcnRfZW5naW5lLCBESF9nZXRfZGVmYXVsdF9vcGVuc3NsX21ldGhvZCgpKTsKCUVOR0lORV9zZXRfUkFORChzbWFydF9lbmdpbmUsIFJBTkRfU1NMZWF5KCkpOwoJRU5HSU5FX3NldF9CTl9tb2RfZXhwKHNtYXJ0X2VuZ2luZSwgQk5fbW9kX2V4cCk7CgoJcmV0dXJuIHNtYXJ0X2VuZ2luZTsKfQojZW5kaWYKCnN0YXRpYyB2b2lkCmNvbnZlcnRfcnNhX3RvX3JzYTEoS2V5ICogaW4sIEtleSAqIG91dCkKewoJc3RydWN0IHNjX3ByaXZfZGF0YSAqcHJpdjsKCglvdXQtPnJzYS0+ZmxhZ3MgPSBpbi0+cnNhLT5mbGFnczsKCW91dC0+ZmxhZ3MgPSBpbi0+ZmxhZ3M7CglSU0Ffc2V0X21ldGhvZChvdXQtPnJzYSwgUlNBX2dldF9tZXRob2QoaW4tPnJzYSkpOwoJQk5fY29weShvdXQtPnJzYS0+biwgaW4tPnJzYS0+bik7CglCTl9jb3B5KG91dC0+cnNhLT5lLCBpbi0+cnNhLT5lKTsKCXByaXYgPSBSU0FfZ2V0X2FwcF9kYXRhKGluLT5yc2EpOwoJcHJpdi0+cmVmX2NvdW50Kys7CglSU0Ffc2V0X2FwcF9kYXRhKG91dC0+cnNhLCBwcml2KTsKCXJldHVybjsKfQoKc3RhdGljIGludApzY19yZWFkX3B1YmtleShLZXkgKiBrLCBjb25zdCBzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqY2VydF9vYmopCnsKCWludCByOwoJc2NfcGtjczE1X2NlcnRfdCAqY2VydCA9IE5VTEw7CglzdHJ1Y3Qgc2NfcHJpdl9kYXRhICpwcml2ID0gTlVMTDsKCXNjX3BrY3MxNV9jZXJ0X2luZm9fdCAqY2luZm8gPSBjZXJ0X29iai0+ZGF0YTsKCglYNTA5ICp4NTA5ID0gTlVMTDsKCUVWUF9QS0VZICpwdWJrZXkgPSBOVUxMOwoJdTggKnA7CgljaGFyICp0bXA7CgoJZGVidWcoInNjX3JlYWRfcHVia2V5KCkgd2l0aCBjZXJ0IGlkICUwMlgiLCBjaW5mby0+aWQudmFsdWVbMF0pOwoJciA9IHNjX3BrY3MxNV9yZWFkX2NlcnRpZmljYXRlKHAxNWNhcmQsIGNpbmZvLCAmY2VydCk7CglpZiAocikgewoJCWxvZ2l0KCJDZXJ0aWZpY2F0ZSByZWFkIGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJZ290byBlcnI7Cgl9Cgl4NTA5ID0gWDUwOV9uZXcoKTsKCWlmICh4NTA5ID09IE5VTEwpIHsKCQlyID0gLTE7CgkJZ290byBlcnI7Cgl9CglwID0gY2VydC0+ZGF0YTsKCWlmICghZDJpX1g1MDkoJng1MDksICZwLCBjZXJ0LT5kYXRhX2xlbikpIHsKCQlsb2dpdCgiVW5hYmxlIHRvIHBhcnNlIFguNTA5IGNlcnRpZmljYXRlIik7CgkJciA9IC0xOwoJCWdvdG8gZXJyOwoJfQoJc2NfcGtjczE1X2ZyZWVfY2VydGlmaWNhdGUoY2VydCk7CgljZXJ0ID0gTlVMTDsKCXB1YmtleSA9IFg1MDlfZ2V0X3B1YmtleSh4NTA5KTsKCVg1MDlfZnJlZSh4NTA5KTsKCXg1MDkgPSBOVUxMOwoJaWYgKHB1YmtleS0+dHlwZSAhPSBFVlBfUEtFWV9SU0EpIHsKCQlsb2dpdCgiUHVibGljIGtleSBpcyBvZiB1bmtub3duIHR5cGUiKTsKCQlyID0gLTE7CgkJZ290byBlcnI7Cgl9CglrLT5yc2EgPSBFVlBfUEtFWV9nZXQxX1JTQShwdWJrZXkpOwoJRVZQX1BLRVlfZnJlZShwdWJrZXkpOwoKCWstPnJzYS0+ZmxhZ3MgfD0gUlNBX0ZMQUdfU0lHTl9WRVI7CglSU0Ffc2V0X21ldGhvZChrLT5yc2EsIHNjX2dldF9yc2FfbWV0aG9kKCkpOwoJcHJpdiA9IHhtYWxsb2Moc2l6ZW9mKHN0cnVjdCBzY19wcml2X2RhdGEpKTsKCXByaXYtPmNlcnRfaWQgPSBjaW5mby0+aWQ7Cglwcml2LT5yZWZfY291bnQgPSAxOwoJUlNBX3NldF9hcHBfZGF0YShrLT5yc2EsIHByaXYpOwoKCWstPmZsYWdzID0gS0VZX0ZMQUdfRVhUOwoJdG1wID0ga2V5X2ZpbmdlcnByaW50KGssIFNTSF9GUF9NRDUsIFNTSF9GUF9IRVgpOwoJZGVidWcoImZpbmdlcnByaW50ICVkICVzIiwga2V5X3NpemUoayksIHRtcCk7Cgl4ZnJlZSh0bXApOwoKCXJldHVybiAwOwplcnI6CglpZiAoY2VydCkKCQlzY19wa2NzMTVfZnJlZV9jZXJ0aWZpY2F0ZShjZXJ0KTsKCWlmIChwdWJrZXkpCgkJRVZQX1BLRVlfZnJlZShwdWJrZXkpOwoJaWYgKHg1MDkpCgkJWDUwOV9mcmVlKHg1MDkpOwoJcmV0dXJuIHI7Cn0KCktleSAqKgpzY19nZXRfa2V5cyhjb25zdCBjaGFyICppZCwgY29uc3QgY2hhciAqcGluKQp7CglLZXkgKmssICoqa2V5czsKCWludCBpLCByLCByZWFsX2NvdW50ID0gMCwga2V5X2NvdW50OwoJc2NfcGtjczE1X2lkX3QgY2VydF9pZDsKCXNjX3BrY3MxNV9vYmplY3RfdCAqY2VydHNbMzJdOwoJY2hhciAqYnVmID0geHN0cmR1cChpZCksICpwOwoKCWRlYnVnKCJzY19nZXRfa2V5cyBjYWxsZWQ6IGlkID0gJXMiLCBpZCk7CgoJaWYgKHNjX3BpbiAhPSBOVUxMKQoJCXhmcmVlKHNjX3Bpbik7CglzY19waW4gPSAocGluID09IE5VTEwpID8gTlVMTCA6IHhzdHJkdXAocGluKTsKCgljZXJ0X2lkLmxlbiA9IDA7CglpZiAoKHAgPSBzdHJjaHIoYnVmLCAnOicpKSAhPSBOVUxMKSB7CgkJKnAgPSAwOwoJCXArKzsKCQlzY19wa2NzMTVfaGV4X3N0cmluZ190b19pZChwLCAmY2VydF9pZCk7Cgl9CglyID0gc3NjYW5mKGJ1ZiwgIiVkIiwgJnNjX3JlYWRlcl9pZCk7Cgl4ZnJlZShidWYpOwoJaWYgKHIgIT0gMSkKCQlnb3RvIGVycjsKCWlmIChwMTVjYXJkID09IE5VTEwpIHsKCQlzY19jbG9zZSgpOwoJCXIgPSBzY19pbml0KCk7CgkJaWYgKHIpIHsKCQkJZXJyb3IoIlNtYXJ0Y2FyZCBpbml0IGZhaWxlZDogJXMiLCBzY19zdHJlcnJvcihyKSk7CgkJCWdvdG8gZXJyOwoJCX0KCX0KCWlmIChjZXJ0X2lkLmxlbikgewoJCXIgPSBzY19wa2NzMTVfZmluZF9jZXJ0X2J5X2lkKHAxNWNhcmQsICZjZXJ0X2lkLCAmY2VydHNbMF0pOwoJCWlmIChyIDwgMCkKCQkJZ290byBlcnI7CgkJa2V5X2NvdW50ID0gMTsKCX0gZWxzZSB7CgkJciA9IHNjX3BrY3MxNV9nZXRfb2JqZWN0cyhwMTVjYXJkLCBTQ19QS0NTMTVfVFlQRV9DRVJUX1g1MDksCgkJCQkJICBjZXJ0cywgMzIpOwoJCWlmIChyID09IDApIHsKCQkJbG9naXQoIk5vIGNlcnRpZmljYXRlcyBmb3VuZCBvbiBzbWFydGNhcmQiKTsKCQkJciA9IC0xOwoJCQlnb3RvIGVycjsKCQl9IGVsc2UgaWYgKHIgPCAwKSB7CgkJCWVycm9yKCJDZXJ0aWZpY2F0ZSBlbnVtZXJhdGlvbiBmYWlsZWQ6ICVzIiwKCQkJICAgICAgc2Nfc3RyZXJyb3IocikpOwoJCQlnb3RvIGVycjsKCQl9CgkJa2V5X2NvdW50ID0gcjsKCX0KCWlmIChrZXlfY291bnQgPiAxMDI0KQoJCWZhdGFsKCJUb28gbWFueSBrZXlzICgldSksIGV4cGVjdGVkIDw9IDEwMjQiLCBrZXlfY291bnQpOwoJa2V5cyA9IHhjYWxsb2Moa2V5X2NvdW50ICogMiArIDEsIHNpemVvZihLZXkgKikpOwoJZm9yIChpID0gMDsgaSA8IGtleV9jb3VudDsgaSsrKSB7CgkJc2NfcGtjczE1X29iamVjdF90ICp0bXBfb2JqID0gTlVMTDsKCQljZXJ0X2lkID0gKChzY19wa2NzMTVfY2VydF9pbmZvX3QgKikoY2VydHNbaV0tPmRhdGEpKS0+aWQ7CgkJaWYgKHNjX3BrY3MxNV9maW5kX3Bya2V5X2J5X2lkKHAxNWNhcmQsICZjZXJ0X2lkLCAmdG1wX29iaikpCgkJCS8qIHNraXAgdGhlIHB1YmxpYyBrZXkgKGNlcnRpZmljYXRlKSBpZiBubwoJCQkgKiBjb3JyZXNwb25kaW5nIHByaXZhdGUga2V5IGlzIHByZXNlbnQgKi8KCQkJY29udGludWU7CgkJayA9IGtleV9uZXcoS0VZX1JTQSk7CgkJaWYgKGsgPT0gTlVMTCkKCQkJYnJlYWs7CgkJciA9IHNjX3JlYWRfcHVia2V5KGssIGNlcnRzW2ldKTsKCQlpZiAocikgewoJCQllcnJvcigic2NfcmVhZF9wdWJrZXkgZmFpbGVkOiAlcyIsIHNjX3N0cmVycm9yKHIpKTsKCQkJa2V5X2ZyZWUoayk7CgkJCWNvbnRpbnVlOwoJCX0KCQlrZXlzW3JlYWxfY291bnRdID0gazsKCQlyZWFsX2NvdW50Kys7CgkJayA9IGtleV9uZXcoS0VZX1JTQTEpOwoJCWlmIChrID09IE5VTEwpCgkJCWJyZWFrOwoJCWNvbnZlcnRfcnNhX3RvX3JzYTEoa2V5c1tyZWFsX2NvdW50LTFdLCBrKTsKCQlrZXlzW3JlYWxfY291bnRdID0gazsKCQlyZWFsX2NvdW50Kys7Cgl9CglrZXlzW3JlYWxfY291bnRdID0gTlVMTDsKCglyZXR1cm4ga2V5czsKZXJyOgoJc2NfY2xvc2UoKTsKCXJldHVybiBOVUxMOwp9CgppbnQKc2NfcHV0X2tleShLZXkgKnBydiwgY29uc3QgY2hhciAqaWQpCnsKCWVycm9yKCJrZXkgdXBsb2FkaW5nIG5vdCB5ZXQgc3VwcG9ydGVkIik7CglyZXR1cm4gLTE7Cn0KCmNoYXIgKgpzY19nZXRfa2V5X2xhYmVsKEtleSAqa2V5KQp7CglpbnQgcjsKCWNvbnN0IHN0cnVjdCBzY19wcml2X2RhdGEgKnByaXY7CglzdHJ1Y3Qgc2NfcGtjczE1X29iamVjdCAqa2V5X29iajsKCglwcml2ID0gKGNvbnN0IHN0cnVjdCBzY19wcml2X2RhdGEgKikgUlNBX2dldF9hcHBfZGF0YShrZXktPnJzYSk7CglpZiAocHJpdiA9PSBOVUxMIHx8IHAxNWNhcmQgPT0gTlVMTCkgewoJCWxvZ2l0KCJTbWFydENhcmQga2V5IG5vdCBsb2FkZWQiKTsKCQkvKiBpbnRlcm5hbCBlcnJvciA9PiByZXR1cm4gZGVmYXVsdCBsYWJlbCAqLwoJCXJldHVybiB4c3RyZHVwKCJzbWFydGNhcmQga2V5Iik7Cgl9CglyID0gc2NfcGtjczE1X2ZpbmRfcHJrZXlfYnlfaWQocDE1Y2FyZCwgJnByaXYtPmNlcnRfaWQsICZrZXlfb2JqKTsKCWlmIChyKSB7CgkJbG9naXQoIlVuYWJsZSB0byBmaW5kIHByaXZhdGUga2V5IGZyb20gU21hcnRDYXJkOiAlcyIsCgkJICAgICAgc2Nfc3RyZXJyb3IocikpOwoJCXJldHVybiB4c3RyZHVwKCJzbWFydGNhcmQga2V5Iik7Cgl9CglpZiAoa2V5X29iaiA9PSBOVUxMIHx8IGtleV9vYmotPmxhYmVsID09IE5VTEwpCgkJLyogdGhlIG9wdGlvbmFsIFBLQ1MjMTUgbGFiZWwgZG9lcyBub3QgZXhpc3RzCgkJICogPT4gcmV0dXJuIHRoZSBkZWZhdWx0IGxhYmVsICovCgkJcmV0dXJuIHhzdHJkdXAoInNtYXJ0Y2FyZCBrZXkiKTsKCXJldHVybiB4c3RyZHVwKGtleV9vYmotPmxhYmVsKTsKfQoKI2VuZGlmIC8qIFNNQVJUQ0FSRCAqLwo=