LyoKICogQlJMVFRZIC0gQSBiYWNrZ3JvdW5kIHByb2Nlc3MgcHJvdmlkaW5nIGFjY2VzcyB0byB0aGUgY29uc29sZSBzY3JlZW4gKHdoZW4gaW4KICogICAgICAgICAgdGV4dCBtb2RlKSBmb3IgYSBibGluZCBwZXJzb24gdXNpbmcgYSByZWZyZXNoYWJsZSBicmFpbGxlIGRpc3BsYXkuCiAqCiAqIENvcHlyaWdodCAoQykgMTk5NS0yMDIzIGJ5IFRoZSBCUkxUVFkgRGV2ZWxvcGVycy4KICoKICogQlJMVFRZIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4KICoKICogVGhpcyBpcyBmcmVlIHNvZnR3YXJlLCBwbGFjZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZQogKiBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55CiAqIGxhdGVyIHZlcnNpb24uIFBsZWFzZSBzZWUgdGhlIGZpbGUgTElDRU5TRS1MR1BMIGZvciBkZXRhaWxzLgogKgogKiBXZWIgUGFnZTogaHR0cDovL2JybHR0eS5hcHAvCiAqCiAqIFRoaXMgc29mdHdhcmUgaXMgbWFpbnRhaW5lZCBieSBEYXZlIE1pZWxrZSA8ZGF2ZUBtaWVsa2UuY2M+LgogKi8KCi8qIEJyYWlsbGVMaXRlL2JyYWlsbGUuYyAtIEJyYWlsbGUgZGlzcGxheSBsaWJyYXJ5CiAqIEZvciBCbGF6aWUgRW5naW5lZXJpbmcncyBCcmFpbGxlIExpdGUgc2VyaWVzCiAqIEF1dGhvcjogTmlraGlsIE5haXIgPG5uMjAxQGN1cy5jYW0uYWMudWs+CiAqIENvcHlyaWdodCAoQykgMTk5OCBieSBOaWtoaWwgTmFpci4KICogU29tZSBhZGRpdGlvbnMgYnk6IE5pY29sYXMgUGl0cmUgPG5pY29AZmx1eG5pYy5uZXQ+CiAqIFNvbWUgbW9kaWZpY2F0aW9ucyBjb3B5cmlnaHQgMjAwMSBieSBTdOlwaGFuZSBEb3lvbiA8cy5kb3lvbkB2aWRlb3Ryb24uY2E+LgogKiBTb21lIGFkZGl0aW9ucyBieTogRGF2ZSBNaWVsa2UgPGRhdmVAbWllbGtlLmNjPgogKi8KCiNpbmNsdWRlICJwcm9sb2d1ZS5oIgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInBhcnNlLmgiCiNpbmNsdWRlICJ0aW1pbmcuaCIKI2luY2x1ZGUgImFzeW5jX3dhaXQuaCIKI2luY2x1ZGUgIm1lc3NhZ2UuaCIKCnR5cGVkZWYgZW51bSB7CiAgUEFSTV9CQVVEUkFURSwKICBQQVJNX0tCRU1VCn0gRHJpdmVyUGFyYW1ldGVyOwojZGVmaW5lIEJSTFBBUk1TICJiYXVkcmF0ZSIsICJrYmVtdSIKCiNpbmNsdWRlICJicmxfZHJpdmVyLmgiCiNpbmNsdWRlICJicmFpbGxlLmgiCiNpbmNsdWRlICJpb19zZXJpYWwuaCIKCiNkZWZpbmUgQkxfTkVFRF9BUlJBWVMKI2luY2x1ZGUgImJpbmRpbmdzLmgiCQkvKiBmb3Iga2V5YmluZGluZ3MgKi8KCiNkZWZpbmUgUVNaIDI1NgkJCS8qIHNpemUgb2YgaW50ZXJuYWwgaW5wdXQgcXVldWUgaW4gYnl0ZXMgKi8KI2RlZmluZSBJTlRfQ1NSX1NQRUVEIDIJCS8qIG9uL29mZiB0aW1lIGluIGN5Y2xlcyAqLwojZGVmaW5lIEFDS19USU1FT1VUIDEwMDAJLyogdGltZW91dCBpbiBtcyBmb3IgYW4gQUNLIHRvIGNvbWUgYmFjayAqLwoKU2VyaWFsRGV2aWNlICpCTF9zZXJpYWxEZXZpY2UgPSBOVUxMOwkJLyogZmlsZSBkZXNjcmlwdG9yIGZvciBCcmFpbGxlIGRpc3BsYXkgKi8KCnN0YXRpYyB1bnNpZ25lZCBjaGFyICpwcmV2ZGF0YSA9IE5VTEw7CS8qIHByZXZpb3VzbHkgcmVjZWl2ZWQgZGF0YSAqLwpzdGF0aWMgdW5zaWduZWQgY2hhciAqcmF3ZGF0YSA9IE5VTEw7CS8qIHdyaXRlYnJsKCkgYnVmZmVyIGZvciByYXcgQnJhaWxsZSBkYXRhICovCnN0YXRpYyBpbnQgYmxpdGVzejsJLyogc2V0IHRvIDE4IG9yIDQwICovCnN0YXRpYyBpbnQgd2FpdGluZ19hY2sgPSAwOwkvKiB3YWl0aW5nIGFja25vd2xlZGdlbWVudCBmbGFnICovCnN0YXRpYyBpbnQgcmV2ZXJzZV9rYmQgPSAwOwkvKiByZXZlcnNlIGtleWJvYXJkIGZsYWcgKi8Kc3RhdGljIGludCBpbnRvdmVycmlkZSA9IDA7CS8qIGludGVybmFsIG92ZXJyaWRlIGZsYWcgLQoJCQkJICogaGlnaGx5IGR1YmlvdXMgYmVoYXZpb3VyIC4uLgoJCQkJICovCnN0YXRpYyBpbnQgaW50X2N1cnNvciA9IDA7CS8qIHBvc2l0aW9uIG9mIGludGVybmFsIGN1cnNvcjogMCA9IG5vbmUgKi8Kc3RhdGljIHVuc2lnbmVkIGludCBrYmVtdSA9IDE7IC8qIGtleWJvYXJkIGVtdWxhdGlvbiAod2hldGhlciB5b3UgY2FuIHR5cGUpICovCgovKiBUaGUgaW5wdXQgcXVldWUgaXMgb25seSBtYW5pcHVsYXRlZCBieSB0aGUgcXB1dCgpIGFuZCBxZ2V0KCkKICogZnVuY3Rpb25zLgogKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgKnFiYXNlID0gTlVMTDsJLyogc3RhcnQgb2YgcXVldWUgaW4gbWVtb3J5ICovCnN0YXRpYyBpbnQgcW9mZiA9IDA7CQkvKiBvZmZzZXQgb2YgZmlyc3QgYnl0ZSAqLwpzdGF0aWMgaW50IHFsZW4gPSAwOwkJLyogbnVtYmVyIG9mIGl0ZW1zIGluIHRoZSBxdWV1ZSAqLwoKCi8qIERhdGEgdHlwZSBmb3IgYSBCcmFpbGxlIExpdGUga2V5LCBpbmNsdWRpbmcgdHJhbnNsYXRpb24gaW50byBjb21tYW5kCiAqIGNvZGVzOgogKi8KdHlwZWRlZiBzdHJ1Y3QKICB7CiAgICB1bnNpZ25lZCBjaGFyIHJhdzsJCS8qIHJhdyB2YWx1ZSwgYWZ0ZXIgYW55IGtleWJvYXJkIHJldmVyc2FsICovCiAgICBpbnQgY21kOwkJCS8qIGNvbW1hbmQgY29kZSAqLwogICAgdW5zaWduZWQgY2hhciBhc2M7CQkvKiBBU0NJSSB0cmFuc2xhdGlvbiBvZiBCcmFpbGxlIGtleXMgKi8KICAgIHVuc2lnbmVkIGNoYXIgc3BjYmFyOwkvKiAxID0gb24sIDAgPSBvZmYgKi8KICAgIHVuc2lnbmVkIGNoYXIgcm91dGluZzsJLyogcm91dGluZyBrZXkgbnVtYmVyICovCiAgfQpibGtleTsKCgpzdGF0aWMgaW50CnFwdXQgKHVuc2lnbmVkIGNoYXIgYykKewogIGlmIChxbGVuID09IFFTWikKICAgIHJldHVybiBFT0Y7CiAgcWJhc2VbKHFvZmYgKyBxbGVuKyspICUgUVNaXSA9IGM7CiAgcmV0dXJuIDA7Cn0KCgpzdGF0aWMgaW50CnFnZXQgKGJsa2V5ICoga3ApCnsKICB1bnNpZ25lZCBjaGFyIGM7CiAgaW50IGhvdzsKICBzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciBjb3VudHNbXSA9IHsxLCAzLCAzfTsKICB1bnNpZ25lZCBjaGFyIGNvdW50OwoKICBpZiAocWxlbiA9PSAwKQogICAgcmV0dXJuIEVPRjsKICBjID0gcWJhc2VbcW9mZl07CgogIC8qIGV4dGVuZGVkIHNlcXVlbmNlcyBzdGFydCB3aXRoIGEgemVybyAqLwogIGhvdyA9IChjID09IDApPyAxOgogICAgICAgIChjID09IDB4ODAgJiYgYmxpdGVzeiAhPSAxOCk/IDI6CiAgICAgICAgMDsKICBjb3VudCA9IGNvdW50c1tob3ddOwogIGlmIChxbGVuIDwgY291bnQpCiAgICByZXR1cm4gRU9GOwoKICBtZW1zZXQgKGtwLCAwLCBzaXplb2YgKCprcCkpOwogIHN3aXRjaCAoaG93KSB7CiAgICBjYXNlIDA6IC8qIG5vbi1leHRlbmRlZCBzZXF1ZW5jZXMgKEJMMTgpICovCiAgICAgIC8qIFdlIG11c3QgZGVhbCB3aXRoIGtleWJvYXJkIHJldmVyc2FsIGhlcmU6ICovCiAgICAgIGlmIChyZXZlcnNlX2tiZCkKCXsKCSAgaWYgKGMgPj0gMHg4MCkJLyogYWR2YW5jZSBiYXIgKi8KCSAgICBjIF49IDB4MDM7CgkgIGVsc2UKCSAgICBjID0gKGMgJiAweDQwKSB8ICgoYyAmIDB4MzgpID4+IDMpIHwgKChjICYgMHgwNykgPDwgMyk7Cgl9CgogICAgICAvKiBOb3cgd2UgZmlsbCBpbiBhbGwgdGhlIGluZm8gYWJvdXQgdGhlIGtleXByZXNzOiAqLwogICAgICBpZiAoYyA+PSAweDgwKQkJLyogYWR2YW5jZSBiYXIgKi8KCXsKCSAga3AtPnJhdyA9IGM7CgkgIHN3aXRjaCAoYykgewoJICAgIGNhc2UgMHg4MzoJCS8qIGxlZnQgKi8KCSAgICAgIGtwLT5jbWQgPSBCTFRfQkFSTFQ7CgkgICAgICBicmVhazsKCgkgICAgY2FzZSAweDgwOgkJLyogcmlnaHQgKi8KCSAgICAgIGtwLT5jbWQgPSBCTFRfQkFSUlQ7CgkgICAgICBicmVhazsKCgkgICAgZGVmYXVsdDoJCS8qIHVucmVjb2duaXNlZCBrZXlwcmVzcyAqLwoJICAgICAga3AtPmNtZCA9IDA7CiAgICAgICAgICAgICAgYnJlYWs7CgkgIH0KCX0KICAgICAgZWxzZQoJewoJICBrcC0+c3BjYmFyID0gKChjICYgMHg0MCk/IDE6IDApOwoJICBjICY9IDB4M2Y7CQkvKiBsZWF2ZSBvbmx5IGRvdCBrZXkgaW5mbyAqLwoJICBrcC0+cmF3ID0gYzsKCSAga3AtPmNtZCA9IGNtZHRyYW5zW2NdOwoJICBrcC0+YXNjID0gYnJsdHJhbnNbY107Cgl9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMTogeyAvKiBleHRlbmRlZCBzZXF1ZW5jZXMgKEJMNDApICovCiAgICAgIHVuc2lnbmVkIGNoYXIgYzIgPSBxYmFzZVsoKHFvZmYgKyAxKSAlIFFTWildOwogICAgICB1bnNpZ25lZCBjaGFyIGMzID0gcWJhc2VbKChxb2ZmICsgMikgJSBRU1opXTsKCiAgICAgIC8qIFdlIG11c3QgZGVhbCB3aXRoIGtleWJvYXJkIHJldmVyc2FsIGhlcmU6ICovCiAgICAgIGlmIChyZXZlcnNlX2tiZCkKCXsKCSAgaWYgKGMyID09IDApCgkgICAgewkJCS8qIGFkdmFuY2UgYmFycyBvciByb3V0aW5nIGtleXMgKi8KCSAgICAgIGlmIChjMyAmIDB4ODApCS8qIGFkdmFuY2UgYmFycyAqLwoJCWMzID0gKChjMyAmIDB4RjApIHwKCQkgICAgICAoKGMzICYgMHgxKSA8PCAzKSB8ICgoYzMgJiAweDIpIDw8IDEpIHwKCQkgICAgICAoKGMzICYgMHg0KSA+PiAxKSB8ICgoYzMgJiAweDgpID4+IDMpKTsKCSAgICAgIGVsc2UgaWYgKGMzID4gMCAmJiBjMyA8PSBibGl0ZXN6KQoJCWMzID0gYmxpdGVzeiAtIGMzICsgMTsKCSAgICB9CgkgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgIGMyID0gKCgoYzIgJiAweDM4KSA+PiAzKSB8ICgoYzIgJiAweDA3KSA8PCAzKSB8CiAgICAgICAgICAgICAgICAgICAgKChjMiAmIDB4NDApIDw8IDEpIHwgKChjMiAmIDB4ODApID4+IDEpKTsKICAgICAgICAgICAgICBjMyA9ICgoYzMgJiAweDQwKSB8ICgoYzMgJiAweDM4KSA+PiAzKSB8ICgoYzMgJiAweDA3KSA8PCAzKSk7CiAgICAgICAgICAgIH0KCX0KCiAgICAgIC8qIE5vdyB3ZSBmaWxsIGluIGFsbCB0aGUgaW5mbyBhYm91dCB0aGUga2V5cHJlc3M6ICovCiAgICAgIGlmIChjMiA9PSAwKQkJLyogYWR2YW5jZSBiYXJzIG9yIHJvdXRpbmcga2V5cyAqLwoJewoJICBrcC0+cmF3ID0gYzM7CgkgIGlmIChjMyAmIDB4ODApCiAgICAgICAgICAgIGtwLT5jbWQgPSAoKmJhcmNtZHMpW2MzICYgMHhGXTsKCSAgZWxzZSBpZiAoYzMgPiAwICYmIGMzIDw9IGJsaXRlc3opCgkgICAga3AtPnJvdXRpbmcgPSBjMzsKCX0KICAgICAgZWxzZQoJewoJICBrcC0+c3BjYmFyID0gKChjMyAmIDB4NDApPyAxOiAwKTsKCSAgYzMgJj0gMHgzZjsJCS8qIGxlYXZlIG9ubHkgZG90IGtleSBpbmZvICovCgkgIGtwLT5yYXcgPSAoYzIgJiAweEMwKSB8IGMzOyAvKiBjb21iaW5lIGluZm8gZm9yIGFsbCA4IGRvdHMgKi8KCSAgLyogYzImMHgzRiBhbmQgYzMmMHgzRiBhcmUgdGhlIHNhbWUsIGkuZS4gZG90cyAxLTYuICovCgkgIGtwLT5jbWQgPSBjbWR0cmFuc1tjM107CgkgIGtwLT5hc2MgPSBicmx0cmFuc1tjM107Cgl9CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGNhc2UgMjogeyAvKiBleHRlbmRlZCBzZXF1ZW5jZXMgKG1pbGxlbm5pdW0pICovCiAgICAgIHVuc2lnbmVkIGNoYXIgYzMgPSBxYmFzZVsoKHFvZmYgKyAyKSAlIFFTWildOwoKICAgICAgLyogV2UgbXVzdCBkZWFsIHdpdGgga2V5Ym9hcmQgcmV2ZXJzYWwgaGVyZTogKi8KICAgICAgaWYgKHJldmVyc2Vfa2JkKQogICAgICAgIGMzID0gKChjMyAmIDB4MTEpIDw8IDMpIHwgKChjMyAmIDB4MjIpIDw8IDEpIHwgKChjMyAmIDB4NDQpID4+IDEpIHwgKChjMyAmIDB4ODgpID4+IDMpOwogICAgICBrcC0+cmF3ID0gYzM7CgogICAgICBpZiAoYzMgJiAweDBmKQogICAgICAgIGtwLT5jbWQgPSAoKmJhcmNtZHMpWygoYzMgJiAweDEpIDw8IDMpIHwgKChjMyAmIDB4MikgPDwgMSkgfCAoKGMzICYgMHg0KSA+PiAxKSB8ICgoYzMgJiAweDgpID4+IDMpXTsKICAgICAgZWxzZSBpZiAoYzMgJiAweDMwKQogICAgICAgIGtwLT5jbWQgPSByd3djbWRzWyhjMyA+PiA0KSAmIDB4M107CiAgICAgIGVsc2UgaWYgKGMzICYgMHhjMCkKICAgICAgICBrcC0+Y21kID0gbHd3Y21kc1soYzMgPj4gNikgJiAweDNdOwogICAgICBlbHNlCiAgICAgICAga3AtPmNtZCA9IDA7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGRlZmF1bHQ6CiAgICAgIGtwLT5jbWQgPSAwOwogICAgICBicmVhazsKICB9CgogIC8qIGFkanVzdCBxdWV1ZSB2YXJpYWJsZXMgZm9yIG5leHQgbWVtYmVyICovCiAgcW9mZiA9IChxb2ZmICsgY291bnQpICUgUVNaOwogIHFsZW4gLT0gY291bnQ7CgogIHJldHVybiAwOwp9CgoKc3RhdGljIHZvaWQKcWZpbGwgKHZvaWQpCnsKICB1bnNpZ25lZCBjaGFyIGM7CQkvKiBjaGFyYWN0ZXIgYnVmZmVyICovCgogIHdoaWxlIChzZXJpYWxSZWFkRGF0YSAoQkxfc2VyaWFsRGV2aWNlLCAmYywgMSwgMCwgMCkgPT0gMSkKICAgIHsKICAgICAgaWYgKHdhaXRpbmdfYWNrICYmIGMgPT0gNSkJLyogXmUgaXMgdGhlIGFja25vd2xlZGdlbWVudCBjaGFyYWN0ZXIgLi4uICovCgl3YWl0aW5nX2FjayA9IDA7CiAgICAgIGVsc2UKCXFwdXQgKGMpOwogICAgfQp9CgoKc3RhdGljIHZvaWQKcWZsdXNoICh2b2lkKQp7CiAgcWZpbGwoKTsKICBxbGVuID0gMDsKfQoKc3RhdGljIGludAphd2FpdF9hY2sgKHZvaWQpIHsKICBUaW1lUGVyaW9kIHBlcmlvZDsKICBzdGFydFRpbWVQZXJpb2QoJnBlcmlvZCwgQUNLX1RJTUVPVVQpOwogIHdhaXRpbmdfYWNrID0gMTsKICBkbyB7CiAgICBhc3luY1dhaXQoMTApOwkvKiBzbGVlcCBmb3IgMTAgbXMgKi8KICAgIHFmaWxsKCk7CiAgICBpZiAoIXdhaXRpbmdfYWNrKSByZXR1cm4gMTsKICB9IHdoaWxlICghYWZ0ZXJUaW1lUGVyaW9kKCZwZXJpb2QsIE5VTEwpKTsKICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKd3JpdGVfcHJlYnJsICh2b2lkKSB7CiAgc3RhdGljIGNvbnN0IHVuc2lnbmVkIGNoYXIgcmVxdWVzdFtdID0gezBYMDUsIDBYNDR9OwkJCS8qIGNvZGUgdG8gc2VuZCBiZWZvcmUgQnJhaWxsZSAqLwogIHNlcmlhbFdyaXRlRGF0YShCTF9zZXJpYWxEZXZpY2UsIHJlcXVlc3QsIHNpemVvZihyZXF1ZXN0KSk7Cn0KCnN0YXRpYyBpbnQKYnJsX2NvbnN0cnVjdCAoQnJhaWxsZURpc3BsYXkgKmJybCwgY2hhciAqKnBhcmFtZXRlcnMsIGNvbnN0IGNoYXIgKmRldmljZSkKewogIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgZ29vZF9iYXVkcmF0ZXNbXSA9CiAgICB7MzAwLDYwMCwxMjAwLDI0MDAsNDgwMCw5NjAwLDE5MjAwLDM4NDAwLCAwfTsKICB1bnNpZ25lZCBpbnQgYmF1ZHJhdGU7CiAgLyogSW5pdCBzdHJpbmcgZm9yIE1vZGVsIGRldGVjdGlvbiAqLwoKICBpZiAoISpwYXJhbWV0ZXJzW1BBUk1fQkFVRFJBVEVdIHx8CiAgICAgICFzZXJpYWxWYWxpZGF0ZUJhdWQoJmJhdWRyYXRlLCAiYmF1ZCByYXRlIiwKCQkgICAgcGFyYW1ldGVyc1tQQVJNX0JBVURSQVRFXSwgZ29vZF9iYXVkcmF0ZXMpKQogICAgYmF1ZHJhdGUgPSBCQVVEUkFURTsKCiAgaWYgKCpwYXJhbWV0ZXJzW1BBUk1fS0JFTVVdKQogICAgaWYgKCF2YWxpZGF0ZVllc05vKCZrYmVtdSwgcGFyYW1ldGVyc1tQQVJNX0tCRU1VXSkpCiAgICAgIGxvZ01lc3NhZ2UoTE9HX1dBUk5JTkcsICIlczogJXMiLCAiaW52YWxpZCBrZXlib2FyZCBlbXVsYXRpb24gc2V0dGluZyIsIHBhcmFtZXRlcnNbUEFSTV9LQkVNVV0pOwogIGtiZW11ID0gISFrYmVtdTsKCiAgaWYgKCFpc1NlcmlhbERldmljZUlkZW50aWZpZXIoJmRldmljZSkpIHsKICAgIHVuc3VwcG9ydGVkRGV2aWNlSWRlbnRpZmllcihkZXZpY2UpOwogICAgcmV0dXJuIDA7CiAgfQoKICBsb2dNZXNzYWdlKExPR19ERUJVRywgIk9wZW5pbmcgc2VyaWFsIHBvcnQ6ICVzIiwgZGV2aWNlKTsKICBpZiAoKEJMX3NlcmlhbERldmljZSA9IHNlcmlhbE9wZW5EZXZpY2UoZGV2aWNlKSkpIHsKICAgIGlmIChzZXJpYWxSZXN0YXJ0RGV2aWNlKEJMX3NlcmlhbERldmljZSwgYmF1ZHJhdGUpKSB7CiAgICAgIGlmIChzZXJpYWxTZXRGbG93Q29udHJvbChCTF9zZXJpYWxEZXZpY2UsIFNFUklBTF9GTE9XX0hBUkRXQVJFKSkgewogICAgICAgIGlmICgocWJhc2UgPSBtYWxsb2MoUVNaKSkpIHsKICAgICAgICAgIHFmbHVzaCgpOwogICAgICAgICAgd3JpdGVfcHJlYnJsKCk7CgogICAgICAgICAgaWYgKGF3YWl0X2FjaygpKSB7CiAgICAgICAgICAgIGxvZ01lc3NhZ2UoTE9HX0RFQlVHLCAiR290IHJlc3BvbnNlLiIpOwoKICAgICAgICAgICAgLyogTmV4dCwgbGV0J3MgZGV0ZWN0IHRoZSBCTFQtTW9kZWwgKDE4LCA0MCwgTTIwLCBNNDApLiAqLwogICAgICAgICAgICBiYXJjbWRzID0gJmJhcjJjbWRzOwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBjZWxsc1sxOF07CgogICAgICAgICAgICAgIG1lbXNldChjZWxscywgMCwgc2l6ZW9mKGNlbGxzKSk7CiAgICAgICAgICAgICAgc2VyaWFsV3JpdGVEYXRhKEJMX3NlcmlhbERldmljZSwgY2VsbHMsIHNpemVvZihjZWxscykpOwogICAgICAgICAgICAgIHdhaXRpbmdfYWNrID0gMTsKICAgICAgICAgICAgICBhc3luY1dhaXQoNDAwKTsKICAgICAgICAgICAgICBxZmlsbCgpOwoKICAgICAgICAgICAgICBpZiAod2FpdGluZ19hY2spIHsKICAgICAgICAgICAgICAgIC8qIG5vIHJlc3BvbnNlLCBzbyBpdCBtdXN0IGJlIEJMVDQwICovCiAgICAgICAgICAgICAgICBibGl0ZXN6ID0gNDA7CiAgICAgICAgICAgICAgICBicmwtPmtleUJpbmRpbmdzID0gIjQwX20yMF9tNDAiOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBibGl0ZXN6ID0gc2l6ZW9mKGNlbGxzKTsKICAgICAgICAgICAgICAgIGJybC0+a2V5QmluZGluZ3MgPSAiMTgiOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgewogICAgICAgICAgICAgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIHJlcXVlc3RbXSA9IHswWDA1LCAwWDU3fTsJCQkvKiBjb2RlIHRvIHNlbmQgYmVmb3JlIEJyYWlsbGUgKi8KCiAgICAgICAgICAgICAgYXN5bmNXYWl0KDIwMCk7CiAgICAgICAgICAgICAgcWZsdXNoKCk7CiAgICAgICAgICAgICAgc2VyaWFsV3JpdGVEYXRhKEJMX3NlcmlhbERldmljZSwgcmVxdWVzdCwgc2l6ZW9mKHJlcXVlc3QpKTsKICAgICAgICAgICAgICB3YWl0aW5nX2FjayA9IDA7CiAgICAgICAgICAgICAgYXN5bmNXYWl0KDIwMCk7CiAgICAgICAgICAgICAgcWZpbGwoKTsKCiAgICAgICAgICAgICAgaWYgKHFsZW4pIHsKICAgICAgICAgICAgICAgIGNoYXIgcmVzcG9uc2VbcWxlbiArIDFdOwogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IDA7CgogICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGJ5dGUgPSBxYmFzZVtxb2ZmICUgUVNaXTsKCiAgICAgICAgICAgICAgICAgIHFvZmYgPSAocW9mZiArIDEpICUgUVNaLCAtLXFsZW47CiAgICAgICAgICAgICAgICAgIGlmICghYnl0ZSkgYnJlYWs7CiAgICAgICAgICAgICAgICAgIHJlc3BvbnNlW2xlbmd0aCsrXSA9IGJ5dGU7CiAgICAgICAgICAgICAgICB9IHdoaWxlIChxbGVuKTsKCiAgICAgICAgICAgICAgICByZXNwb25zZVtsZW5ndGhdID0gMDsKICAgICAgICAgICAgICAgIGxvZ01lc3NhZ2UoTE9HX0lORk8sICJCcmFpbGxlIExpdGUgaWRlbnRpdHk6ICVzIiwgcmVzcG9uc2UpOwoKICAgICAgICAgICAgICAgIGlmICgocmVzcG9uc2VbMF0gPT0gJ1gnKSAmJgogICAgICAgICAgICAgICAgICAgIChyZXNwb25zZVsxXSA9PSAnICcpICYmCiAgICAgICAgICAgICAgICAgICAgKHJlc3BvbnNlWzJdID09ICdCJykpIHsKICAgICAgICAgICAgICAgICAgYmxpdGVzeiA9IGF0b2koJnJlc3BvbnNlWzNdKTsKICAgICAgICAgICAgICAgICAgaWYgKGJsaXRlc3ogPD0gMjApIGJhcmNtZHMgPSAmYmFyMWNtZHM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBsb2dNZXNzYWdlKExPR19OT1RJQ0UsICJCcmFpbGxlIExpdGUgJWQgZGV0ZWN0ZWQuIiwgYmxpdGVzeik7CiAgICAgICAgICAgIGJybC0+dGV4dENvbHVtbnMgPSBibGl0ZXN6OwkvKiBpbml0aWFsaXNlIHNpemUgb2YgZGlzcGxheSAtICovCiAgICAgICAgICAgIGJybC0+dGV4dFJvd3MgPSAxOwkJLyogQnJhaWxsZSBMaXRlcyBhcmUgc2luZ2xlIGxpbmUgZGlzcGxheXMgKi8KCiAgICAgICAgICAgIG1ha2VPdXRwdXRUYWJsZShkb3RzVGFibGVfSVNPMTE1NDhfMSk7CiAgICAgICAgICAgIG1ha2VJbnB1dFRhYmxlKCk7CgogICAgICAgICAgICAvKiBBbGxvY2F0ZSBzcGFjZSBmb3IgYnVmZmVycyAqLwogICAgICAgICAgICBpZiAoKHByZXZkYXRhID0gbWFsbG9jKGJybC0+dGV4dENvbHVtbnMpKSkgewogICAgICAgICAgICAgIG1lbXNldChwcmV2ZGF0YSwgMCwgYnJsLT50ZXh0Q29sdW1ucyk7CgogICAgICAgICAgICAgIGlmICgocmF3ZGF0YSA9IG1hbGxvYyhicmwtPnRleHRDb2x1bW5zKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwoKICAgICAgICAgICAgICAvL2ZyZWUocmF3ZGF0YSk7CiAgICAgICAgICAgICAgLy9yYXdkYXRhID0gTlVMTDsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbG9nTWFsbG9jRXJyb3IoKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGZyZWUocHJldmRhdGEpOwogICAgICAgICAgICAgIHByZXZkYXRhID0gTlVMTDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBsb2dNYWxsb2NFcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsb2dNZXNzYWdlKExPR19ERUJVRywgIkJyYWlsbGVMaXRlIG5vdCByZXNwb25kaW5nLiIpOwogICAgICAgICAgfQoKICAgICAgICAgIGZyZWUocWJhc2UpOwogICAgICAgICAgcWJhc2UgPSBOVUxMOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsb2dNYWxsb2NFcnJvcigpOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIHNlcmlhbENsb3NlRGV2aWNlKEJMX3NlcmlhbERldmljZSk7CiAgICBCTF9zZXJpYWxEZXZpY2UgPSBOVUxMOwogIH0KCiAgcmV0dXJuIDA7Cn0KCgpzdGF0aWMgdm9pZApicmxfZGVzdHJ1Y3QgKEJyYWlsbGVEaXNwbGF5ICogYnJsKQp7CiAgaWYgKHJhd2RhdGEpIHsKICAgIGZyZWUocmF3ZGF0YSk7CiAgICByYXdkYXRhID0gTlVMTDsKICB9CgogIGlmIChwcmV2ZGF0YSkgewogICAgZnJlZShwcmV2ZGF0YSk7CiAgICBwcmV2ZGF0YSA9IE5VTEw7CiAgfQoKICBpZiAocWJhc2UpIHsKICAgIGZyZWUocWJhc2UpOwogICAgcWJhc2UgPSBOVUxMOwogIH0KCiAgaWYgKEJMX3NlcmlhbERldmljZSkgewogICAgc2VyaWFsQ2xvc2VEZXZpY2UoQkxfc2VyaWFsRGV2aWNlKTsKICAgIEJMX3NlcmlhbERldmljZSA9IE5VTEw7CiAgfQp9CgoKc3RhdGljIGludApicmxfd3JpdGVXaW5kb3cgKEJyYWlsbGVEaXNwbGF5ICogYnJsLCBjb25zdCB3Y2hhcl90ICp0ZXh0KQp7CiAgc2hvcnQgaTsJCQkvKiBsb29wIGNvdW50ZXIgKi8KCiAgLyogSWYgdGhlIGludG92ZXJyaWRlIGZsYWcgaXMgc2V0LCB0aGVuIGNhbGxzIHRvIHdyaXRlYnJsKCkgZnJvbSB0aGUgbWFpbgogICAqIG1vZHVsZSBhcmUgaWdub3JlZCwgYmVjYXVzZSB0aGUgZGlzcGxheSBpcyBpbiBpbnRlcm5hbCB1c2UuCiAgICogVGhpcyBpcyBoaWdobHkgYW50aXNvY2lhbCBiZWhhdmlvdXIhCiAgICovCiAgaWYgKGludG92ZXJyaWRlKQogICAgcmV0dXJuIDE7CgogIC8qIEZpcnN0LCB0aGUgaW50ZXJuYWwgY3Vyc29yOiAqLwogIGlmIChpbnRfY3Vyc29yKQogICAgewogICAgICBzdGF0aWMgaW50IHRpbWVyID0gMDsJCS8qIGZvciBpbnRlcm5hbCBjdXJzb3IgKi8KICAgICAgdGltZXIgPSAodGltZXIgKyAxKSAlIChJTlRfQ1NSX1NQRUVEICogMik7CiAgICAgIGJybC0+YnVmZmVyW2ludF9jdXJzb3IgLSAxXSA9ICh0aW1lciA8IElOVF9DU1JfU1BFRUQpPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChCUkxfRE9UMSB8IEJSTF9ET1QyIHwgQlJMX0RPVDMgfCBCUkxfRE9UNyk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEJSTF9ET1Q0IHwgQlJMX0RPVDUgfCBCUkxfRE9UNiB8IEJSTF9ET1Q4KTsKICAgIH0KCiAgLyogTmV4dCB3ZSBtdXN0IGhhbmRsZSBkaXNwbGF5IHJldmVyc2FsOiAqLwogIGlmIChyZXZlcnNlX2tiZCkgewogICAgZm9yIChpPTA7IGk8YmxpdGVzejsgaSs9MSkgewogICAgICByYXdkYXRhW2ldID0gdHJhbnNsYXRlSW5wdXRDZWxsKGJybC0+YnVmZmVyW2JsaXRlc3ogLSAxIC0gaV0pOwogICAgfQogIH0gZWxzZSB7CiAgICBtZW1jcHkocmF3ZGF0YSwgYnJsLT5idWZmZXIsIGJsaXRlc3opOwogIH0KCiAgLyogT25seSByZWZyZXNoIGRpc3BsYXkgaWYgdGhlIGRhdGEgaGFzIGNoYW5nZWQ6ICovCiAgaWYgKGNlbGxzSGF2ZUNoYW5nZWQocHJldmRhdGEsIHJhd2RhdGEsIGJsaXRlc3osIE5VTEwsIE5VTEwsIE5VTEwpKQogICAgewogICAgICAvKiBEb3QgbWFwcGluZyBmcm9tIHN0YW5kYXJkIHRvIEJyYWlsbGVMaXRlOiAqLwogICAgICB0cmFuc2xhdGVPdXRwdXRDZWxscyhyYXdkYXRhLCByYXdkYXRhLCBibGl0ZXN6KTsKCiAgICAgIC8qIEZpcnN0IHdlIHByb2Nlc3MgYW55IHBlbmRpbmcga2V5c3Ryb2tlcywganVzdCBpbiBjYXNlIGFueSBvZiB0aGVtCiAgICAgICAqIGFyZSBeZSAuLi4KICAgICAgICovCiAgICAgIHdhaXRpbmdfYWNrID0gMDsJCS8qIE5vdCByZWFsbHkgbmVjZXNzYXJ5LCBidXQgLi4uICovCiAgICAgIHFmaWxsICgpOwoKICAgICAgLyogTmV4dCB3ZSBzZW5kIHRoZSBeZUQgc2VxdWVuY2UsIGFuZCB3YWl0IGZvciBhbiBBQ0sgKi8KICAgICAgd2FpdGluZ19hY2sgPSAxOwogICAgICAvKiBzZW5kIHRoZSBeRUQuLi4gKi8KICAgICAgd3JpdGVfcHJlYnJsKCk7CiAgICAgIGlmICghYXdhaXRfYWNrKCkpIHJldHVybiAxOwoKICAgICAgLyogT0ssIG5vdyB3ZSdsbCBzdXBwb3NlIHdlJ3JlIGFsbCBjbGVhciB0byBzZW5kIEJyYWlsbGUgZGF0YS4gKi8KICAgICAgc2VyaWFsV3JpdGVEYXRhKEJMX3NlcmlhbERldmljZSwgcmF3ZGF0YSwgYmxpdGVzeik7CiAgICAgIGF3YWl0X2FjaygpOwogICAgfQogIHJldHVybiAxOwp9CgoKc3RhdGljIGludApicmxfcmVhZENvbW1hbmQgKEJyYWlsbGVEaXNwbGF5ICpicmwsIEtleVRhYmxlQ29tbWFuZENvbnRleHQgY29udGV4dCkKewogIHN0YXRpYyBlbnVtIHsKICAgIFNUX05PUk1BTCwJLyogdHJhbnNwYXJlbnQgKi8KICAgIFNUX0NVUlNPUiwJLyogcG9zaXRpb24gaW50ZXJuYWwgY3Vyc29yICovCiAgICBTVF9SRVBFQVQsCS8qIHNldCByZXBlYXQgY291bnQgKi8KICAgIFNUX0NPTkZJRwkvKiBwcmVmZXJlbmNlcyBvcHRpb25zICovCiAgfSBzdGF0ZSA9IFNUX05PUk1BTDsKICBzdGF0aWMgaW50IHJlcGVhdCA9IDA7CQkvKiByZXBlYXQgY291bnQgZm9yIGNvbW1hbmQgKi8KICBzdGF0aWMgaW50IHJlcGVhdE5leHQgPSAwOyAvKiBmbGFnIHRvIGluZGljYXRlICB3aGV0aGVyIDAgd2UgcmVwZWF0IHRoZQoJCQkJc2FtZSBjb21tYW5kIG9yIDEgd2UgZ2V0IHRoZSBuZXh0IGNvbW1hbmQKCQkJCWFuZCByZXBlYXQgdGhhdC4gKi8KICBzdGF0aWMgaW50IGhvbGQsIHNoaWZ0LCBzaGlmdGxjaywgY3RybCwgbWV0YTsKI2lmZGVmIFVTRV9URVhUVFJBTlMKICBzdGF0aWMgaW50IGRvdDhzaGlmdDsKI2VuZGlmIC8qIFVTRV9URVhUVFJBTlMgKi8KICBzdGF0aWMgYmxrZXkga2V5OwogIHN0YXRpYyBjaGFyIG91dG1zZ1s0MV07CiAgaW50IHRlbXAgPSBCUkxfQ01EX05PT1A7CgogYWdhaW46CiAgaWYocmVwZWF0TmV4dCB8fCByZXBlYXQgPT0gMCkgewogICAgLyogUHJvY2VzcyBhbnkgbmV3IGtleXN0cm9rZXM6ICovCiAgICBxZmlsbCAoKTsKICAgIGlmIChxZ2V0ICgma2V5KSA9PSBFT0YpCS8qIG5vIGtleXMgdG8gcHJvY2VzcyAqLwogICAgICByZXR1cm4gRU9GOwogICAgcmVwZWF0TmV4dCA9IDA7CiAgfQogIGlmKHJlcGVhdD4wKQogICAgcmVwZWF0LS07CgogIC8qIE91ciBvdmVyYWxsIGJlaGF2aW91ciBkZXBlbmRzIG9uIHRoZSBzdGF0ZSB2YXJpYWJsZSAoc2VlIGFib3ZlKS4gKi8KICBzd2l0Y2ggKHN0YXRlKQogICAgewogICAgY2FzZSBTVF9OT1JNQUw6CQkJLyogdHJhbnNwYXJlbnQgKi8KICAgICAgLyogRmlyc3Qgd2UgZGVhbCB3aXRoIGV4dGVybmFsIGNvbW1hbmRzOiAqLwogICAgICBkbwoJewoJICAvKiBpZiBpdCdzIG5vdCBhbiBleHRlcm5hbCBjb21tYW5kLCBnbyBvbiAqLwoJICBpZiAoIWtleS5jbWQpCgkgICAgYnJlYWs7CgoJICAvKiBpZiBhZHZhbmNlIGJhciwgcmV0dXJuIHdpdGggY29ycmVzcG9uZGluZyBjb21tYW5kICovCgkgIGlmIChrZXkuYXNjID09IDApCgkgICAgcmV0dXJuIGtleS5jbWQ7CgoJICAvKiBJIHRob3VnaHQgSSB3YXMgc21hcnQgd2hlbiBJIHN1Z2dlc3RlZCB0byByZW1vdmUgQ01EX0NVVF9FTkQuCgkgICAgIFdlbGwgbm93IHRoZXJlJ3MgdGhpcyBuYXN0eSBleGNlcHRpb246IHRoZSBjb21tYW5kIG9mZnNldAoJICAgICBkZXBlbmRzIG9uIHRoZSBkaXNwbGF5IHNpemUhICovCgkgIGlmKGtleS5jbWQgPT0gQlJMX0NNRF9CTEsoQ09QWV9SRUNUKSB8fCBrZXkuY21kID09IEJSTF9DTURfQkxLKENPUFlfTElORSkpCgkgICAga2V5LmNtZCArPSBibGl0ZXN6LTE7CgoJICBpZihrZXkuc3BjYmFyICYmIChrZXkuY21kICZCUkxfTVNLX0JMSykgPT0gQlJMX0NNRF9CTEsoUEFTU0tFWSkpIHsKICAgICAgICAgIC8qCgkgICAgaWYoIWtiZW11KQoJICAgICAgcmV0dXJuIEVPRjsKICAgICAgICAgICovCgkgICAgaWYgKCFzaGlmdGxjaykKCSAgICAgIHNoaWZ0ID0gMDsKCSAgICBjdHJsID0gbWV0YSA9IDA7CiNpZmRlZiBVU0VfVEVYVFRSQU5TCgkgICAgZG90OHNoaWZ0ID0gMDsKI2VuZGlmIC8qIFVTRV9URVhUVFJBTlMgKi8KCSAgfQoKCSAgLyogYWx3YXlzIE9LIGlmIGNob3JkZWQgKi8KCSAgaWYgKGtleS5zcGNiYXIpCgkgICAgcmV0dXJuIGtleS5jbWQ7CgoJICAvKiBrYmVtdSBjb3VsZCBiZSBvbiwgdGhlbiBnbyBvbiAqLwoJICBpZiAoa2JlbXUgJiYgY29udGV4dCA9PSBLVEJfQ1RYX0RFRkFVTFQpCgkgICAgYnJlYWs7CgoJICAvKiBpZiBpdCdzIGEgZGFuZ2Vyb3VzIGNvbW1hbmQgaXQgc2hvdWxkIGhhdmUgYmVlbiBjaG9yZGVkICovCgkgIGlmIChkYW5nY21kWyhrZXkucmF3ICYgMHgzOCkgPj4gM10gJiAoMSA8PCAoa2V5LnJhdyAmIDB4MDcpKSkKCSAgICBicmVhazsKCgkgIC8qIGZpbmFsbHkgd2UgYXJlIE9LICovCgkgIHJldHVybiBrZXkuY21kOwoJfQogICAgICB3aGlsZSAoMCk7CgogICAgICAvKiBOZXh0LCBpbnRlcm5hbCBjb21tYW5kczogKi8KICAgICAgaWYgKGtleS5zcGNiYXIpCglzd2l0Y2ggKGtleS5hc2MpCgkgIHsKCSAgY2FzZSBCTFRfS0JFTVU6CS8qIHNldCBrZXlib2FyZCBlbXVsYXRpb24gKi8KCSAgICBrYmVtdSBePSAxOwoJICAgIHNoaWZ0ID0gc2hpZnRsY2sgPSBjdHJsID0gbWV0YSA9IDA7CiNpZmRlZiBVU0VfVEVYVFRSQU5TCgkgICAgZG90OHNoaWZ0ID0gMDsKI2VuZGlmIC8qIFVTRV9URVhUVFJBTlMgKi8KCSAgICBpZihrYmVtdSkKCSAgICAgIG1lc3NhZ2UgKE5VTEwsIGdldHRleHQoImtleWJvYXJkIGVtdSBvbiIpLCBNU0dfU0lMRU5UKTsKCSAgICBlbHNlIG1lc3NhZ2UgKE5VTEwsIGdldHRleHQoImtleWJvYXJkIGVtdSBvZmYiKSwgTVNHX1NJTEVOVCk7CgkgICAgcmV0dXJuIEJSTF9DTURfTk9PUDsKCSAgY2FzZSBCTFRfUk9UQVRFOgkvKiByb3RhdGUgQnJhaWxsZSBMaXRlIGJ5IDE4MCBkZWdyZWVzICovCgkgICAgcmV2ZXJzZV9rYmQgXj0gMTsKCSAgICByZXR1cm4gQlJMX0NNRF9OT09QOwoJICBjYXNlIEJMVF9QT1NJVE46CS8qIHBvc2l0aW9uIGludGVybmFsIGN1cnNvciAqLwoJICAgIGludF9jdXJzb3IgPSBibGl0ZXN6IC8gMjsKCSAgICBzdGF0ZSA9IFNUX0NVUlNPUjsKCSAgICByZXR1cm4gQlJMX0NNRF9OT09QOwoJICBjYXNlIEJMVF9SRVBFQVQ6CS8qIHNldCByZXBlYXQgY291bnQgKi8KCSAgICBob2xkID0gMDsKCSAgICBzbnByaW50ZiAob3V0bXNnLCBzaXplb2Yob3V0bXNnKSwgIiVzOiIsIGdldHRleHQoInJlcGVhdCBjb3VudCIpKTsKCSAgICBtZXNzYWdlIChOVUxMLCBvdXRtc2csIE1TR19TSUxFTlQgfCBNU0dfTk9ERUxBWSk7CgkgICAgaW50b3ZlcnJpZGUgPSAxOwoJICAgIHN0YXRlID0gU1RfUkVQRUFUOwoJICAgIHJldHVybiBCUkxfQ01EX05PT1A7CgkgIGNhc2UgQkxUX0NPTkZJRzoJLyogY29uZmlndXJhdGlvbiBtZW51ICovCgkgICAgc25wcmludGYgKG91dG1zZywgc2l6ZW9mKG91dG1zZyksICIlcz8gW20vcy9yL3pdIiwgZ2V0dGV4dCgiY29uZmlnIikpOwoJICAgIG1lc3NhZ2UgKE5VTEwsIG91dG1zZywgTVNHX1NJTEVOVCB8IE1TR19OT0RFTEFZKTsKCSAgICBpbnRvdmVycmlkZSA9IDE7CgkgICAgc3RhdGUgPSBTVF9DT05GSUc7CgkgICAgcmV0dXJuIEJSTF9DTURfTk9PUDsKCSAgY2FzZSAnICc6CQkvKiBwcmFjdGljYWwgZXhjZXB0aW9uIGZvciAqLwoJICAgIC8qIElmIGtleWJvYXJkIG1vZGUgb2ZmLCBzcGFjZSBiYXIgPT0gQlJMX0NNRF9IT01FICovCgkgICAgaWYgKCFrYmVtdSB8fCBjb250ZXh0ICE9IEtUQl9DVFhfREVGQVVMVCkKCSAgICAgIHJldHVybiBCUkxfQ01EX0hPTUU7CgkgIH0KCiAgICAgIC8qIGNoZWNrIGZvciByb3V0aW5nIGtleXMgKi8KICAgICAgaWYgKGtleS5yb3V0aW5nKQoJcmV0dXJuIChCUkxfQ01EX0JMSyhST1VURSkgKyBrZXkucm91dGluZyAtIDEpOwoKICAgICAgaWYgKCFrYmVtdSkKCXJldHVybiBCUkxfQ01EX05PT1A7CgogICAgICAvKiBOb3cga2JlbXUgaXMgZGVmaW5pdGVseSBvbi4gKi8KICAgICAgc3dpdGNoIChrZXkucmF3ICYgMHhDMCkKCXsKCWNhc2UgMHg0MDoJCS8qIGRvdCA3ICovCgkgIHNoaWZ0ID0gMTsKCSAgYnJlYWs7CgljYXNlIDB4QzA6CQkvKiBkb3QgNzggKi8KCSAgY3RybCA9IDE7CgkgIGJyZWFrOwoJY2FzZSAweDgwOgkJLyogZG90IDggKi8KI2lmZGVmIFVTRV9URVhUVFJBTlMKCSAgZG90OHNoaWZ0ID0gMTsKI2Vsc2UgLyogVVNFX1RFWFRUUkFOUyAqLwoJICBtZXRhID0gMTsKI2VuZGlmIC8qIFVTRV9URVhUVFJBTlMgKi8KCSAgYnJlYWs7Cgl9CgogICAgICBpZiAoa2V5LnNwY2JhciAmJiBrZXkuYXNjICE9ICcgJykKCXN3aXRjaCAoa2V5LmFzYykKCSAgewoJICBjYXNlIEJMVF9VUENBU0U6CS8qIHVwcGVyIGNhc2UgbmV4dCAqLwoJICAgIGlmIChzaGlmdCkKCSAgICAgIHNoaWZ0bGNrID0gMTsKCSAgICBlbHNlCgkgICAgICBzaGlmdCA9IDE7CgkgICAgcmV0dXJuIEJSTF9DTURfTk9PUDsKCSAgY2FzZSBCTFRfVVBDT0ZGOgkvKiBjYW5jZWwgdXBwZXIgY2FzZSAqLwoJICAgIHNoaWZ0ID0gc2hpZnRsY2sgPSAwOwoJICAgIHJldHVybiBCUkxfQ01EX05PT1A7CgkgIGNhc2UgQkxUX0NUUkw6CS8qIGNvbnRyb2wgbmV4dCAqLwoJICAgIGN0cmwgPSAxOwoJICAgIHJldHVybiBCUkxfQ01EX05PT1A7CiNpZmRlZiBVU0VfVEVYVFRSQU5TCgkgIGNhc2UgQkxUX0RPVDhTSElGVDoJLyogYWRkIGRvdCA4IHRvIG5leHQgcGF0dGVybiAqLwoJICAgIGRvdDhzaGlmdCA9IDE7CgkgICAgcmV0dXJuIEJSTF9DTURfTk9PUDsKI2VuZGlmIC8qIFVTRV9URVhUVFJBTlMgKi8KCSAgY2FzZSBCTFRfTUVUQToJLyogbWV0YSBuZXh0ICovCgkgICAgbWV0YSA9IDE7CgkgICAgcmV0dXJuIEJSTF9DTURfTk9PUDsKCSAgY2FzZSBCTFRfQUJPUlQ6CS8qIGFib3J0IC0gcXVpdCBrZXlib2FyZCBlbXVsYXRpb24gKi8KCSAgICBrYmVtdSA9IDA7CgkgICAgbWVzc2FnZSAoTlVMTCwgZ2V0dGV4dCgia2V5Ym9hcmQgZW11IG9mZiIpLCBNU0dfU0lMRU5UKTsKCSAgICByZXR1cm4gQlJMX0NNRF9OT09QOwoJICBkZWZhdWx0OgkJLyogdW5yZWNvZ25pc2VkIGNvbW1hbmQgKi8KCSAgICBzaGlmdCA9IHNoaWZ0bGNrID0gY3RybCA9IG1ldGEgPSAwOwojaWZkZWYgVVNFX1RFWFRUUkFOUwoJICAgIGRvdDhzaGlmdCA9IDA7CiNlbmRpZiAvKiBVU0VfVEVYVFRSQU5TICovCgkgICAgcmV0dXJuIEJSTF9DTURfTk9PUDsKCSAgfQoKICAgICAgLyogT0ssIGl0J3MgYW4gb3JkaW5hcnkgKG5vbi1jaG9yZGVkKSBrZXlzdHJva2UsIGFuZCBrYmVtdSBpcyBvbi4gKi8KI2lmbmRlZiBVU0VfVEVYVFRSQU5TCiAgICAgIGlmIChjdHJsICYmIGtleS5hc2MgPj0gOTYpCgkvKiBvbGQgY29kZSB3YXMgKGtleS5hc2MgJiAweDFmKSAqLwoJdGVtcCA9IEJSTF9DTURfQkxLKFBBU1NDSEFSKSB8IGtleS5hc2MgfCBCUkxfRkxHX0lOUFVUX0NPTlRST0w7CiAgICAgIGVsc2UgaWYgKG1ldGEgJiYga2V5LmFzYyA+PSA5NikKCXRlbXAgPSBCUkxfQ01EX0JMSyhQQVNTQ0hBUikgfCBrZXkuYXNjIHwgQlJMX0ZMR19JTlBVVF9NRVRBOwogICAgICBlbHNlIGlmIChzaGlmdCAmJiAoa2V5LmFzYyAmIDB4NDApKQoJLyogb2xkIGNvZGUgd2FzIChrZXkuYXNjICYgMHhkZikgKi8KCXRlbXAgPSBCUkxfQ01EX0JMSyhQQVNTQ0hBUikgfCBrZXkuYXNjIHwgQlJMX0ZMR19JTlBVVF9TSElGVDsKICAgICAgZWxzZQoJdGVtcCA9IEJSTF9DTURfQkxLKFBBU1NDSEFSKSB8IGtleS5hc2M7CiNlbHNlIC8qIFVTRV9URVhUVFJBTlMgKi8KICAgICAgdGVtcCA9IEJSTF9DTURfQkxLKFBBU1NET1RTKSB8Cgkoa2V5c190b19kb3RzW2tleS5yYXcgJjB4M0ZdCgkgfCAoKG1ldGEpID8gQlJMX0ZMR19JTlBVVF9NRVRBIDogMCkKCSB8ICgoY3RybCkgPyAoQlJMX0RPVDcgfCBCUkxfRE9UOCkgOiAKCSAgICAoc2hpZnQpID8gQlJMX0RPVDcgOiAKCSAgICAoZG90OHNoaWZ0KSA/IEJSTF9ET1Q4IDogMCkpOwojZW5kaWYgLyogVVNFX1RFWFRUUkFOUyAqLwogICAgICBpZiAoIXNoaWZ0bGNrKQoJc2hpZnQgPSAwOwogICAgICBjdHJsID0gbWV0YSA9IDA7CiNpZmRlZiBVU0VfVEVYVFRSQU5TCiAgICAgIGRvdDhzaGlmdCA9IDA7CiNlbmRpZiAvKiBVU0VfVEVYVFRSQU5TICovCiAgICAgIG91dG1zZ1swXSA9IDA7CiAgICAgIHJldHVybiB0ZW1wOwoKICAgIGNhc2UgU1RfQ1VSU09SOgkJCS8qIHBvc2l0aW9uIGludGVybmFsIGN1cnNvciAqLwogICAgICBzd2l0Y2ggKGtleS5jbWQpCgl7CgljYXNlIEJSTF9DTURfSE9NRToJCS8qIGdvIHRvIG1pZGRsZSAqLwoJICBpbnRfY3Vyc29yID0gYmxpdGVzeiAvIDI7CgkgIGJyZWFrOwoJY2FzZSBCUkxfQ01EX0xOQkVHOgkvKiBiZWdpbm5pbmcgb2YgZGlzcGxheSAqLwoJICBpbnRfY3Vyc29yID0gMTsKCSAgYnJlYWs7CgljYXNlIEJSTF9DTURfTE5FTkQ6CS8qIGVuZCBvZiBkaXNwbGF5ICovCgkgIGludF9jdXJzb3IgPSBibGl0ZXN6OwoJICBicmVhazsKCWNhc2UgQlJMX0NNRF9GV0lOTFQ6CS8qIHF1YXJ0ZXIgbGVmdCAqLwoJICBpbnRfY3Vyc29yID0gTUFYIChpbnRfY3Vyc29yIC0gYmxpdGVzeiAvIDQsIDEpOwoJICBicmVhazsKCWNhc2UgQlJMX0NNRF9GV0lOUlQ6CS8qIHF1YXJ0ZXIgcmlnaHQgKi8KCSAgaW50X2N1cnNvciA9IE1JTiAoaW50X2N1cnNvciArIGJsaXRlc3ogLyA0LCBibGl0ZXN6KTsKCSAgYnJlYWs7CgljYXNlIEJSTF9DTURfQ0hSTFQ6CS8qIG9uZSBjaGFyYWN0ZXIgbGVmdCAqLwoJICBpZiAoaW50X2N1cnNvciA+IDEpCgkgICAgaW50X2N1cnNvci0tOwoJICBicmVhazsKCWNhc2UgQlJMX0NNRF9DSFJSVDoJLyogb25lIGNoYXJhY3RlciByaWdodCAqLwoJICBpZiAoaW50X2N1cnNvciA8IGJsaXRlc3opCgkgICAgaW50X2N1cnNvcisrOwoJICBicmVhazsKCWNhc2UgQlJMX0NNRF9CTEsoUk9VVEUpOgkvKiByb3V0ZSBjdXJzb3IgKi8KCSAgaWYgKGtleS5zcGNiYXIpCgkgICAgewoJICAgICAgdGVtcCA9IEJSTF9DTURfQkxLKFJPVVRFKSArIGludF9jdXJzb3IgLSAxOwoJICAgICAgaW50X2N1cnNvciA9IDA7CgkgICAgICBzdGF0ZSA9IFNUX05PUk1BTDsKCSAgICB9CgkgIHJldHVybiB0ZW1wOwoJY2FzZSBCUkxfQ01EX0JMSyhDTElQX05FVyk6CS8qIGJlZ2luIGNvcHkgKi8KCWNhc2UgQlJMX0NNRF9CTEsoQ0xJUF9BREQpOgoJICBpZiAoa2V5LnNwY2JhcikKCSAgICB7CgkgICAgICB0ZW1wID0ga2V5LmNtZCArIGludF9jdXJzb3IgLSAxOwoJICAgICAgaW50X2N1cnNvciA9IDA7CgkgICAgICBzdGF0ZSA9IFNUX05PUk1BTDsKCSAgICB9CgkgIHJldHVybiB0ZW1wOwoJY2FzZSBCUkxfQ01EX0JMSyhDT1BZX1JFQ1QpOgkvKiBlbmQgY29weSAqLwoJY2FzZSBCUkxfQ01EX0JMSyhDT1BZX0xJTkUpOgoJICBpZiAoa2V5LnNwY2JhcikKCSAgICB7CgkgICAgICB0ZW1wID0ga2V5LmNtZCArIGludF9jdXJzb3IgLSAxOwoJICAgICAgaW50X2N1cnNvciA9IDA7CgkgICAgICBzdGF0ZSA9IFNUX05PUk1BTDsKCSAgICB9CgkgIHJldHVybiB0ZW1wOwoJY2FzZSBCUkxfQ01EX0RJU1BNRDogLyogYXR0cmlidXRlIGluZm8gKi8KCSAgdGVtcCA9IEJSTF9DTURfQkxLKERFU0NDSEFSKSArIGludF9jdXJzb3IgLSAxOwoJICBpbnRfY3Vyc29yID0gMDsKCSAgc3RhdGUgPSBTVF9OT1JNQUw7CgkgIHJldHVybiB0ZW1wOwoJZGVmYXVsdDoKCSAgaWYgKGtleS5hc2MgPT0gQkxUX0FCT1JUKSB7CiAgICAgICAgICAgIC8qIGNhbmNlbCBjdXJzb3IgcG9zaXRpb25pbmcgKi8KCSAgICBpbnRfY3Vyc29yID0gMDsKCSAgICBzdGF0ZSA9IFNUX05PUk1BTDsKICAgICAgICAgIH0KCSAgYnJlYWs7Cgl9CiAgICAgIGlmIChrZXkucm91dGluZykKCWludF9jdXJzb3IgPSBrZXkucm91dGluZzsKICAgICAgcmV0dXJuIEJSTF9DTURfTk9PUDsKICAgIGNhc2UgU1RfUkVQRUFUOgkJCS8qIHNldCByZXBlYXQgY291bnQgKi8KICAgICAgaWYgKGtleS5hc2MgPj0gJzAnICYmIGtleS5hc2MgPD0gJzknKQoJewoJICBob2xkID0gKGhvbGQgKiAxMCArIGtleS5hc2MgLSAnMCcpICUgMTAwOwoJICBpZiAoaG9sZCkgewoJICAgIHNucHJpbnRmIChvdXRtc2csIHNpemVvZihvdXRtc2cpLCAiJXM6ICVkIiwgZ2V0dGV4dCgicmVwZWF0IGNvdW50IiksIGhvbGQpOwoJICB9IGVsc2UgewogICAgICAgICAgICBzbnByaW50ZiAob3V0bXNnLCBzaXplb2Yob3V0bXNnKSwgIiVzOiAiLCBnZXR0ZXh0KCJyZXBlYXQgY291bnQiKSk7CiAgICAgICAgICB9CgkgIGludG92ZXJyaWRlID0gMDsKCSAgbWVzc2FnZSAoTlVMTCwgb3V0bXNnLCBNU0dfU0lMRU5UIHwgTVNHX05PREVMQVkpOwoJICBpbnRvdmVycmlkZSA9IDE7Cgl9CiAgICAgIGVsc2UgaWYgKGtleS5yb3V0aW5nKQoJewoJICBob2xkID0ga2V5LnJvdXRpbmcgKzE7CgkgIHNucHJpbnRmIChvdXRtc2csIHNpemVvZihvdXRtc2cpLCAiJXM6ICVkIiwgZ2V0dGV4dCgicmVwZWF0IGNvdW50IiksIGhvbGQpOwoJICBpbnRvdmVycmlkZSA9IDA7CgkgIG1lc3NhZ2UgKE5VTEwsIG91dG1zZywgTVNHX1NJTEVOVCB8IE1TR19OT0RFTEFZKTsKCSAgaW50b3ZlcnJpZGUgPSAxOwoJfQogICAgICBlbHNlIHsKCWludG92ZXJyaWRlID0gMDsKCW91dG1zZ1swXSA9IDA7CglzdGF0ZSA9IFNUX05PUk1BTDsKCWlmIChob2xkID4gMCkgewoJICBpZiAoa2V5LmFzYyA9PSBTV0lUQ0hWVF9ORVhUIHx8IGtleS5hc2MgPT0gU1dJVENIVlRfUFJFVikKCSAgICAvKiBUaGF0J3MgY2hvcmRlZCBvciBub3QuLi4gKi8KCSAgICByZXR1cm4gQlJMX0NNRF9CTEsoU1dJVENIVlQpICsgKGhvbGQtMSk7CgkgIGVsc2UgaWYgKGtleS5hc2MgPT0gT19TRVRNQVJLKQoJICAgIHJldHVybiBCUkxfQ01EX0JMSyhTRVRNQVJLKSArIChob2xkLTEpOwoJICBlbHNlIGlmIChrZXkuYXNjID09IE9fR09UT01BUkspCgkgICAgcmV0dXJuIEJSTF9DTURfQkxLKEdPVE9NQVJLKSArIChob2xkLTEpOwoJICBlbHNlIGlmIChrZXkuc3BjYmFyKQkJLyogY2hvcmRlZCAqLwoJICAgIHN3aXRjaCAoa2V5LmFzYykKCSAgICAgIHsKCSAgICAgIGNhc2UgQkxUX0VORENNRDoJLyogc2V0IHJlcGVhdCBjb3VudCAqLwoJCWlmIChob2xkID4gMSkgewoJCSAgLyogcmVwZWF0IG5leHQgY29tbWFuZCAqLwoJCSAgcmVwZWF0ID0gaG9sZDsKCQkgIHJlcGVhdE5leHQgPSAxOwoJCX0KCQkvKiBmYWxsIHRocm91Z2ggKi8KCSAgICAgIGNhc2UgQkxUX0FCT1JUOgkvKiBhYm9ydCBvciBlbmRjbWQgKi8KCQlyZXR1cm4gQlJMX0NNRF9OT09QOwoJICAgICAgfQoJICAvKiBpZiB0aGUga2V5IGlzIGFueSBvdGhlciwgc3RhcnQgcmVwZWF0aW5nIGl0LiAqLwoJICByZXBlYXQgPSBob2xkOwoJICBnb3RvIGFnYWluOwoJfQogICAgICB9CiAgICAgIHJldHVybiBCUkxfQ01EX05PT1A7CiAgICBjYXNlIFNUX0NPTkZJRzoJCQkvKiBwcmVmZXJlbmNlcyBvcHRpb25zICovCiAgICAgIHN3aXRjaCAoa2V5LmFzYykKCXsKCWNhc2UgJ20nOgkJLyogcHJlZmVyZW5jZXMgbWVudSAqLwoJICBpbnRvdmVycmlkZSA9IDA7CgkgIHN0YXRlID0gU1RfTk9STUFMOwoJICByZXR1cm4gQlJMX0NNRF9QUkVGTUVOVTsKCWNhc2UgJ3MnOgkJLyogc2F2ZSBwcmVmZXJlbmNlcyAqLwoJICBpbnRvdmVycmlkZSA9IDA7CgkgIHN0YXRlID0gU1RfTk9STUFMOwoJICByZXR1cm4gQlJMX0NNRF9QUkVGU0FWRTsKCWNhc2UgJ3InOgkJLyogcmVzdG9yZSBzYXZlZCBwcmVmZXJlbmNlcyAqLwoJICBpbnRvdmVycmlkZSA9IDA7CgkgIHN0YXRlID0gU1RfTk9STUFMOwoJICByZXR1cm4gQlJMX0NNRF9QUkVGTE9BRDsKCWNhc2UgQkxUX0FCT1JUOgkvKiBhYm9ydCAqLwoJICBpbnRvdmVycmlkZSA9IDA7CgkgIHN0YXRlID0gU1RfTk9STUFMOwoJZGVmYXVsdDoJCS8qIGluIGFueSBjYXNlICovCgkgIHJldHVybiBCUkxfQ01EX05PT1A7Cgl9CiAgICB9CgogIC8qIFdlIHNob3VsZCBuZXZlciByZWFjaCB0aGlzIHBvaW50IC4uLiAqLwogIHJldHVybiBFT0Y7Cn0K