diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..674336e --- /dev/null +++ b/.clang-format @@ -0,0 +1,216 @@ +--- +Language: Cpp +# BasedOnStyle: Microsoft +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: false +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: false + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: BinPack +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 1000 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Right +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RequiresClausePosition: OwnLine +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/src/cli.cpp b/src/cli.cpp index e66b431..2d4976d 100644 --- a/src/cli.cpp +++ b/src/cli.cpp @@ -31,22 +31,27 @@ CLI::~CLI() BN_free(genOrder); } -bool CLI::loadJSON(const fs::path& filename, json *output) { - if (!filename.empty() && !fs::exists(filename)) { +bool CLI::loadJSON(const fs::path &filename, json *output) +{ + if (!filename.empty() && !fs::exists(filename)) + { fmt::print("ERROR: File {} does not exist\n", filename.string()); return false; } - else if (fs::exists(filename)) { + else if (fs::exists(filename)) + { std::ifstream f(filename); *output = json::parse(f, nullptr, false, false); } - else if (filename.empty()) { + else if (filename.empty()) + { cmrc::embedded_filesystem fs = cmrc::umskt::get_filesystem(); cmrc::file keys = fs.open("keys.json"); *output = json::parse(keys, nullptr, false, false); } - if (output->is_discarded()) { + if (output->is_discarded()) + { fmt::print("ERROR: Unable to parse keys from {}\n", filename.string()); return false; } @@ -54,16 +59,18 @@ bool CLI::loadJSON(const fs::path& filename, json *output) { return true; } - -void CLI::showHelp(char *argv[]) { +void CLI::showHelp(char *argv[]) +{ fmt::print("usage: {} \n", argv[0]); fmt::print("\t-h --help\tshow this message\n"); fmt::print("\t-v --verbose\tenable verbose output\n"); fmt::print("\t-n --number\tnumber of keys to generate (defaults to 1)\n"); fmt::print("\t-f --file\tspecify which keys file to load\n"); fmt::print("\t-i --instid\tinstallation ID used to generate confirmation ID\n"); - fmt::print("\t-m --mode\tproduct family to activate.\n\t\t\tvalid options are \"WINDOWS\", \"OFFICEXP\", \"OFFICE2K3\", \"OFFICE2K7\" or \"PLUSDME\"\n\t\t\t(defaults to \"WINDOWS\")\n"); - fmt::print("\t-p --productid\tthe product ID of the Program to activate. only required for Office 2K3 and Office 2K7 programs\n"); + fmt::print("\t-m --mode\tproduct family to activate.\n\t\t\tvalid options are \"WINDOWS\", \"OFFICEXP\", " + "\"OFFICE2K3\", \"OFFICE2K7\" or \"PLUSDME\"\n\t\t\t(defaults to \"WINDOWS\")\n"); + fmt::print("\t-p --productid\tthe product ID of the Program to activate. only required for Office 2K3 and Office " + "2K7 programs\n"); fmt::print("\t-b --binkid\tspecify which BINK identifier to load (defaults to 2E)\n"); fmt::print("\t-l --list\tshow which products/binks can be loaded\n"); fmt::print("\t-c --channelid\tspecify which Channel Identifier to use (defaults to 640)\n"); @@ -74,186 +81,243 @@ void CLI::showHelp(char *argv[]) { fmt::print("\n"); } -int CLI::parseCommandLine(int argc, char* argv[], Options* options) { +int CLI::parseCommandLine(int argc, char *argv[], Options *options) +{ // set default options - *options = Options { - "2E", - "", - "", - "", - "", - 640, - 0, - 1, - false, - false, - false, - false, - false, - false, - false, - MODE_BINK1998_GENERATE, - WINDOWS - }; + *options = Options{"2E", "", "", "", "", 640, 0, 1, + false, false, false, false, false, false, false, MODE_BINK1998_GENERATE, + WINDOWS}; - for (int i = 1; i < argc; i++) { + for (int i = 1; i < argc; i++) + { std::string arg = argv[i]; - if (arg == "-v" || arg == "--verbose") { + if (arg == "-v" || arg == "--verbose") + { options->verbose = true; UMSKT::setDebugOutput(stderr); - } else if (arg == "-h" || arg == "--help") { + } + else if (arg == "-h" || arg == "--help") + { options->help = true; - } else if (arg == "-n" || arg == "--number") { - if (i == argc - 1) { + } + else if (arg == "-n" || arg == "--number") + { + if (i == argc - 1) + { options->error = true; break; } int nKeys; - if (!sscanf(argv[i+1], "%d", &nKeys)) { + if (!sscanf(argv[i + 1], "%d", &nKeys)) + { options->error = true; - } else { + } + else + { options->numKeys = nKeys; } i++; - } else if (arg == "-b" || arg == "--bink") { - if (i == argc - 1) { + } + else if (arg == "-b" || arg == "--bink") + { + if (i == argc - 1) + { options->error = true; break; } - options->binkid = argv[i+1]; + options->binkid = argv[i + 1]; i++; - } else if (arg == "-l" || arg == "--list") { + } + else if (arg == "-l" || arg == "--list") + { options->list = true; - } else if (arg == "-c" || arg == "--channelid") { - if (i == argc - 1) { + } + else if (arg == "-c" || arg == "--channelid") + { + if (i == argc - 1) + { options->error = true; break; } int siteID; - if (!sscanf(argv[i+1], "%d", &siteID)) { + if (!sscanf(argv[i + 1], "%d", &siteID)) + { options->error = true; - } else { + } + else + { options->channelID = siteID; } i++; - } else if (arg == "-s" || arg == "--serial") { - if (i == argc - 1) { + } + else if (arg == "-s" || arg == "--serial") + { + if (i == argc - 1) + { options->error = true; break; } int serial_val; - if (!sscanf(argv[i+1], "%d", &serial_val)) { + if (!sscanf(argv[i + 1], "%d", &serial_val)) + { options->error = true; - } else { + } + else + { options->serialSet = true; options->serial = serial_val; } i++; - } else if (arg == "-u" || arg == "--upgrade") { - options->upgrade = true; - } else if (arg == "-f" || arg == "--file") { - if (i == argc - 1) { + } + else if (arg == "-u" || arg == "--upgrade") + { + options->upgrade = true; + } + else if (arg == "-f" || arg == "--file") + { + if (i == argc - 1) + { options->error = true; break; } - options->keysFilename = argv[i+1]; + options->keysFilename = argv[i + 1]; i++; - } else if (arg == "-i" || arg == "--instid") { - if (i == argc - 1) { + } + else if (arg == "-i" || arg == "--instid") + { + if (i == argc - 1) + { options->error = true; break; } - options->instid = argv[i+1]; + options->instid = argv[i + 1]; options->applicationMode = MODE_CONFIRMATION_ID; i++; - } else if (arg == "-m" || arg == "--mode") { - std::string mode = argv[i+1]; + } + else if (arg == "-m" || arg == "--mode") + { + std::string mode = argv[i + 1]; char *p = &mode[0]; - for (; *p; p++) { + for (; *p; p++) + { *p = toupper((unsigned char)*p); - } + } p = &mode[0]; - if (strcmp(p, "WINDOWS") == 0) { + if (strcmp(p, "WINDOWS") == 0) + { options->activationMode = WINDOWS; - } else if (strcmp(p, "OFFICEXP") == 0) { + } + else if (strcmp(p, "OFFICEXP") == 0) + { options->activationMode = OFFICE_XP; - } else if (strcmp(p, "OFFICE2K3") == 0) { + } + else if (strcmp(p, "OFFICE2K3") == 0) + { options->activationMode = OFFICE_2K3; - } else if (strcmp(p, "OFFICE2K7") == 0) { + } + else if (strcmp(p, "OFFICE2K7") == 0) + { options->activationMode = OFFICE_2K7; - } else if (strcmp(p, "PLUSDME") == 0) { + } + else if (strcmp(p, "PLUSDME") == 0) + { options->activationMode = PLUS_DME; - } + } i++; - } else if (arg == "-p" || arg == "--productid") { - if (i == argc -1) { + } + else if (arg == "-p" || arg == "--productid") + { + if (i == argc - 1) + { options->error = true; break; - } - options->productid = argv[i+1]; + } + options->productid = argv[i + 1]; i++; - } else if (arg == "-V" || arg == "--validate") { - if (i == argc - 1) { + } + else if (arg == "-V" || arg == "--validate") + { + if (i == argc - 1) + { options->error = true; break; } - options->keyToCheck = argv[i+1]; + options->keyToCheck = argv[i + 1]; options->applicationMode = MODE_BINK1998_VALIDATE; i++; - - } else if (arg == "-N" || arg == "--nonewlines") { - options->nonewlines = true; - } else { + } + else if (arg == "-N" || arg == "--nonewlines") + { + options->nonewlines = true; + } + else + { options->error = true; } } // make sure that a product id is entered for OFFICE_2K3 or OFFICE_2K7 IIDs - if ((options->activationMode == OFFICE_2K3 || options->activationMode == OFFICE_2K7) && (options->productid.empty() || options->instid.empty()) ) { + if ((options->activationMode == OFFICE_2K3 || options->activationMode == OFFICE_2K7) && + (options->productid.empty() || options->instid.empty())) + { return options->error = true; } return !options->error; } -int CLI::validateCommandLine(Options* options, char *argv[], json *keys) { - if (options->help || options->error) { - if (options->error) { +int CLI::validateCommandLine(Options *options, char *argv[], json *keys) +{ + if (options->help || options->error) + { + if (options->error) + { fmt::print("error parsing command line options\n"); } showHelp(argv); return 1; } - if (options->verbose) { - if(options->keysFilename.empty()) { + if (options->verbose) + { + if (options->keysFilename.empty()) + { fmt::print("Loading internal keys file\n"); - } else { + } + else + { fmt::print("Loading keys file {}\n", options->keysFilename); } } - if (!loadJSON(options->keysFilename, keys)) { + if (!loadJSON(options->keysFilename, keys)) + { return 2; } - if (options->verbose) { - if(options->keysFilename.empty()) { + if (options->verbose) + { + if (options->keysFilename.empty()) + { fmt::print("Loaded internal keys file successfully\n"); - } else { - fmt::print("Loaded keys from {} successfully\n",options->keysFilename); + } + else + { + fmt::print("Loaded keys from {} successfully\n", options->keysFilename); } } - if (options->list) { - for (auto const el : (*keys)["Products"].items()) { + if (options->list) + { + for (auto const el : (*keys)["Products"].items()) + { int id; sscanf((el.value()["BINK"][0]).get().c_str(), "%x", &id); std::cout << el.key() << ": " << el.value()["BINK"] << std::endl; @@ -269,23 +333,28 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) { sscanf(options->binkid.c_str(), "%x", &intBinkID); // FE and FF are BINK 1998, but do not generate valid keys, so we throw an error - if (intBinkID >= 0xFE) { + if (intBinkID >= 0xFE) + { fmt::print("ERROR: Terminal Services BINKs (FE and FF) are unsupported at this time\n"); return 1; } - - if (intBinkID >= 0x40) { + + if (intBinkID >= 0x40) + { // set bink2002 validate mode if in bink1998 validate mode, else set bink2002 generate mode - options->applicationMode = (options->applicationMode == MODE_BINK1998_VALIDATE) ? MODE_BINK2002_VALIDATE : MODE_BINK2002_GENERATE; + options->applicationMode = + (options->applicationMode == MODE_BINK1998_VALIDATE) ? MODE_BINK2002_VALIDATE : MODE_BINK2002_GENERATE; } - if (options->channelID > 999) { + if (options->channelID > 999) + { fmt::print("ERROR: refusing to create a key with a Channel ID greater than 999\n"); return 1; } // don't allow any serial not between 0 and 999999 - if (options->serial > 999999 || options->serial < 0) { + if (options->serial > 999999 || options->serial < 0) + { fmt::print("ERROR: refusing to create a key with a Serial not between 000000 and 999999\n"); return 1; } @@ -293,7 +362,8 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) { return 0; } -void CLI::printID(DWORD *pid) { +void CLI::printID(DWORD *pid) +{ char raw[12]; char b[6], c[8]; int i, digit = 0; @@ -311,42 +381,51 @@ void CLI::printID(DWORD *pid) { // Make checksum digit-part {...56X-} assert(strlen(c) == 6); for (i = 0; i < 6; i++) - digit -= c[i] - '0'; // Sum digits + { + digit -= c[i] - '0'; // Sum digits + } while (digit < 0) + { digit += 7; + } c[6] = digit + '0'; c[7] = 0; fmt::print("> Product ID: PPPPP-{}-{}-23xxx\n", b, c); } -void CLI::printKey(char *pk) { +void CLI::printKey(char *pk) +{ assert(strlen(pk) >= PK_LENGTH); std::string spk = pk; - fmt::print("{}-{}-{}-{}-{}", - spk.substr(0,5), - spk.substr(5,5), - spk.substr(10,5), - spk.substr(15,5), - spk.substr(20,5)); + fmt::print("{}-{}-{}-{}-{}", spk.substr(0, 5), spk.substr(5, 5), spk.substr(10, 5), spk.substr(15, 5), + spk.substr(20, 5)); } -bool CLI::stripKey(const char *in_key, char out_key[PK_LENGTH]) { +bool CLI::stripKey(const char *in_key, char out_key[PK_LENGTH]) +{ // copy out the product key stripping out extraneous characters const char *p = in_key; size_t i = 0; - for (; *p; p++) { + for (; *p; p++) + { // strip out space or dash - if (*p == ' ' || *p == '-') - continue; + if (*p == ' ' || *p == '-') + { + continue; + } // check if we've passed the product key length to avoid overflow if (i >= PK_LENGTH) + { return false; + } // convert to uppercase - if character allowed, copy into array - for (int j = 0; j < strlen(PIDGEN3::pKeyCharset); j++) { - if (toupper(*p) == PIDGEN3::pKeyCharset[j]) { + for (int j = 0; j < strlen(PIDGEN3::pKeyCharset); j++) + { + if (toupper(*p) == PIDGEN3::pKeyCharset[j]) + { out_key[i++] = toupper(*p); continue; } @@ -356,7 +435,8 @@ bool CLI::stripKey(const char *in_key, char out_key[PK_LENGTH]) { return (i == PK_LENGTH); } -CLI::CLI(Options options, json keys) { +CLI::CLI(Options options, json keys) +{ this->options = options; this->keys = keys; @@ -371,10 +451,11 @@ CLI::CLI(Options options, json keys) { this->genOrder = BN_new(); /* Computed data */ - BN_dec2bn(&this->genOrder, this->keys["BINK"][this->BINKID]["n"]. get().c_str()); + BN_dec2bn(&this->genOrder, this->keys["BINK"][this->BINKID]["n"].get().c_str()); BN_dec2bn(&this->privateKey, this->keys["BINK"][this->BINKID]["priv"].get().c_str()); - if (options.verbose) { + if (options.verbose) + { fmt::print("----------------------------------------------------------- \n"); fmt::print("Loaded the following elliptic curve parameters: BINK[{}]\n", this->BINKID); fmt::print("----------------------------------------------------------- \n"); @@ -390,33 +471,33 @@ CLI::CLI(Options options, json keys) { fmt::print("\n"); } - - eCurve = PIDGEN3::initializeEllipticCurve( - this->keys["BINK"][this->BINKID]["p"].get(), - this->keys["BINK"][this->BINKID]["a"].get(), - this->keys["BINK"][this->BINKID]["b"].get(), - this->keys["BINK"][this->BINKID]["g"]["x"].get(), - this->keys["BINK"][this->BINKID]["g"]["y"].get(), - this->keys["BINK"][this->BINKID]["pub"]["x"].get(), - this->keys["BINK"][this->BINKID]["pub"]["y"].get(), - this->genPoint, - this->pubPoint - ); + eCurve = PIDGEN3::initializeEllipticCurve(this->keys["BINK"][this->BINKID]["p"].get(), + this->keys["BINK"][this->BINKID]["a"].get(), + this->keys["BINK"][this->BINKID]["b"].get(), + this->keys["BINK"][this->BINKID]["g"]["x"].get(), + this->keys["BINK"][this->BINKID]["g"]["y"].get(), + this->keys["BINK"][this->BINKID]["pub"]["x"].get(), + this->keys["BINK"][this->BINKID]["pub"]["y"].get(), + this->genPoint, this->pubPoint); this->count = 0; this->total = this->options.numKeys; } -int CLI::BINK1998Generate() { +int CLI::BINK1998Generate() +{ // raw PID/serial value - DWORD nRaw = this->options.channelID * 1'000'000 ; /* <- change */ + DWORD nRaw = this->options.channelID * 1'000'000; /* <- change */ // using user-provided serial - if (this->options.serialSet) { + if (this->options.serialSet) + { // just in case, make sure it's less than 999999 int serialRnd = (this->options.serial % 999999); nRaw += serialRnd; - } else { + } + else + { // generate a random number to use as a serial BIGNUM *bnrand = BN_new(); BN_rand(bnrand, 19, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY); @@ -426,10 +507,11 @@ int CLI::BINK1998Generate() { sscanf(cRaw, "%d", &oRaw); nRaw += (oRaw % 999999); // ensure our serial is less than 999999 - BN_free(bnrand); + BN_free(bnrand); } - if (this->options.verbose) { + if (this->options.verbose) + { // print the resulting Product ID // PID value is printed in BINK1998::Generate printID(&nRaw); @@ -438,22 +520,29 @@ int CLI::BINK1998Generate() { // generate a key BN_sub(this->privateKey, this->genOrder, this->privateKey); - for (int i = 0; i < this->total; i++) { - PIDGEN3::BINK1998::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, nRaw, options.upgrade, this->pKey); + for (int i = 0; i < this->total; i++) + { + PIDGEN3::BINK1998::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, nRaw, + options.upgrade, this->pKey); bool isValid = PIDGEN3::BINK1998::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey); - if (isValid) { + if (isValid) + { CLI::printKey(this->pKey); - if (i < this->total - 1 || this->options.verbose) { + if (i < this->total - 1 || this->options.verbose) + { fmt::print("\n"); } this->count += isValid; } - else { - if (this->options.verbose) { + else + { + if (this->options.verbose) + { CLI::printKey(this->pKey); fmt::print(" [Invalid]"); - if (i < this->total - 1) { + if (i < this->total - 1) + { fmt::print("\n"); } } @@ -461,49 +550,61 @@ int CLI::BINK1998Generate() { } } - if (this->options.verbose) { + if (this->options.verbose) + { fmt::print("\nSuccess count: {}/{}", this->count, this->total); } - if (!options.nonewlines) { - fmt::print("\n"); + if (!options.nonewlines) + { + fmt::print("\n"); } return 0; } -int CLI::BINK2002Generate() { +int CLI::BINK2002Generate() +{ DWORD pChannelID = this->options.channelID; - if (this->options.verbose) { + if (this->options.verbose) + { fmt::print("> Channel ID: {:03d}\n", this->options.channelID); } // generate a key - for (int i = 0; i < this->total; i++) { + for (int i = 0; i < this->total; i++) + { DWORD pAuthInfo; RAND_bytes((BYTE *)&pAuthInfo, 4); pAuthInfo &= BITMASK(10); - if (this->options.verbose) { + if (this->options.verbose) + { fmt::print("> AuthInfo: {}\n", pAuthInfo); } - PIDGEN3::BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, pAuthInfo, options.upgrade, this->pKey); + PIDGEN3::BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, + pAuthInfo, options.upgrade, this->pKey); bool isValid = PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey); - if (isValid) { + if (isValid) + { CLI::printKey(this->pKey); - if (i < this->total - 1 || this->options.verbose) { // check if end of list or verbose + if (i < this->total - 1 || this->options.verbose) + { // check if end of list or verbose fmt::print("\n"); } this->count += isValid; // add to count } - else { - if (this->options.verbose) { + else + { + if (this->options.verbose) + { CLI::printKey(this->pKey); // print the key - fmt::print(" [Invalid]"); // and add " [Invalid]" to the key - if (i < this->total - 1) { // check if end of list + fmt::print(" [Invalid]"); // and add " [Invalid]" to the key + if (i < this->total - 1) + { // check if end of list fmt::print("\n"); } } @@ -511,28 +612,33 @@ int CLI::BINK2002Generate() { } } - if (this->options.verbose) { + if (this->options.verbose) + { fmt::print("\nSuccess count: {}/{}", this->count, this->total); } - if (!this->options.nonewlines) { - fmt::print("\n"); + if (!this->options.nonewlines) + { + fmt::print("\n"); } return 0; } -int CLI::BINK1998Validate() { +int CLI::BINK1998Validate() +{ char product_key[PK_LENGTH]{}; - if (!CLI::stripKey(this->options.keyToCheck.c_str(), product_key)) { + if (!CLI::stripKey(this->options.keyToCheck.c_str(), product_key)) + { fmt::print("ERROR: Product key is in an incorrect format!\n"); return 1; } CLI::printKey(product_key); fmt::print("\n"); - if (!PIDGEN3::BINK1998::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) { + if (!PIDGEN3::BINK1998::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) + { fmt::print("ERROR: Product key is invalid! Wrong BINK ID?\n"); return 1; } @@ -541,17 +647,20 @@ int CLI::BINK1998Validate() { return 0; } -int CLI::BINK2002Validate() { +int CLI::BINK2002Validate() +{ char product_key[PK_LENGTH]{}; - if (!CLI::stripKey(this->options.keyToCheck.c_str(), product_key)) { + if (!CLI::stripKey(this->options.keyToCheck.c_str(), product_key)) + { fmt::print("ERROR: Product key is in an incorrect format!\n"); return 1; } CLI::printKey(product_key); fmt::print("\n"); - if (!PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) { + if (!PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) + { fmt::print("ERROR: Product key is invalid! Wrong BINK ID?\n"); return 1; } @@ -560,46 +669,45 @@ int CLI::BINK2002Validate() { return 0; } -int CLI::ConfirmationID() { +int CLI::ConfirmationID() +{ char confirmation_id[49]; - int err = ConfirmationID::Generate(this->options.instid.c_str(), confirmation_id, options.activationMode, options.productid); - switch (err) { - case ERR_TOO_SHORT: - fmt::print("ERROR: Installation ID is too short.\n"); - return 1; + auto confid = new class ConfirmationID(); + int err = confid->Generate(this->options.instid.c_str(), confirmation_id, options.productid); - case ERR_TOO_LARGE: - fmt::print("ERROR: Installation ID is too long.\n"); - return 1; + if (err == SUCCESS) + { + fmt::print(confirmation_id); + if (!this->options.nonewlines) + { + fmt::print("\n"); + } + return 0; + } - case ERR_INVALID_CHARACTER: - fmt::print("ERROR: Invalid character in installation ID.\n"); - return 1; + switch (err) + { + case ERR_TOO_SHORT: + fmt::print("ERROR: Installation ID is too short.\n"); - case ERR_INVALID_CHECK_DIGIT: - fmt::print("ERROR: Installation ID checksum failed. Please check that it is typed correctly.\n"); - return 1; + case ERR_TOO_LARGE: + fmt::print("ERROR: Installation ID is too long.\n"); - case ERR_UNKNOWN_VERSION: - fmt::print("ERROR: Unknown installation ID version.\n"); - return 1; + case ERR_INVALID_CHARACTER: + fmt::print("ERROR: Invalid character in installation ID.\n"); - case ERR_UNLUCKY: - fmt::print("ERROR: Unable to generate valid confirmation ID.\n"); - return 1; + case ERR_INVALID_CHECK_DIGIT: + fmt::print("ERROR: Installation ID checksum failed. Please check that it is typed correctly.\n"); - case SUCCESS: - fmt::print(confirmation_id); - if (!this->options.nonewlines) { - fmt::print("\n"); - } - return 0; + case ERR_UNKNOWN_VERSION: + fmt::print("ERROR: Unknown installation ID version.\n"); - default: - fmt::print("Unknown error occurred during Confirmation ID generation: {}\n", err); + case ERR_UNLUCKY: + fmt::print("ERROR: Unable to generate valid confirmation ID.\n"); + + default: + fmt::print("Unknown error occurred during Confirmation ID generation: {}\n", err); } return 1; } - - diff --git a/src/cli.h b/src/cli.h index de8f568..84ace37 100644 --- a/src/cli.h +++ b/src/cli.h @@ -27,24 +27,26 @@ #include +#include "libumskt/confid/confid.h" #include "libumskt/libumskt.h" #include "libumskt/pidgen2/PIDGEN2.h" -#include "libumskt/pidgen3/PIDGEN3.h" #include "libumskt/pidgen3/BINK1998.h" #include "libumskt/pidgen3/BINK2002.h" -#include "libumskt/confid/confid.h" +#include "libumskt/pidgen3/PIDGEN3.h" CMRC_DECLARE(umskt); -enum MODE { +enum MODE +{ MODE_BINK1998_GENERATE = 0, MODE_BINK2002_GENERATE = 1, - MODE_CONFIRMATION_ID = 2, + MODE_CONFIRMATION_ID = 2, MODE_BINK1998_VALIDATE = 3, MODE_BINK2002_VALIDATE = 4, }; -struct Options { +struct Options +{ std::string binkid; std::string keysFilename; std::string instid; @@ -65,24 +67,25 @@ struct Options { ACTIVATION_ALGORITHM activationMode; }; -class CLI { +class CLI +{ Options options; json keys; - const char* BINKID; + const char *BINKID; BIGNUM *privateKey, *genOrder; EC_POINT *genPoint, *pubPoint; EC_GROUP *eCurve; char pKey[25]; int count, total; -public: + public: CLI(Options options, json keys); ~CLI(); - static bool loadJSON(const fs::path& filename, json *output); + static bool loadJSON(const fs::path &filename, json *output); static void showHelp(char *argv[]); - static int parseCommandLine(int argc, char* argv[], Options *options); - static int validateCommandLine(Options* options, char *argv[], json *keys); + static int parseCommandLine(int argc, char *argv[], Options *options); + static int validateCommandLine(Options *options, char *argv[], json *keys); static void printID(DWORD *pid); static void printKey(char *pk); static bool stripKey(const char *in_key, char out_key[PK_LENGTH]); @@ -94,4 +97,4 @@ public: int ConfirmationID(); }; -#endif //UMSKT_CLI_H +#endif // UMSKT_CLI_H diff --git a/src/header.h b/src/header.h index 9600584..3ef7e48 100644 --- a/src/header.h +++ b/src/header.h @@ -25,12 +25,12 @@ #include "typedefs.h" -#include -#include #include +#include +#include #include -#include #include +#include #include #include @@ -38,4 +38,4 @@ using json = nlohmann::json; namespace fs = std::filesystem; -#endif //UMSKT_HEADER_H +#endif // UMSKT_HEADER_H diff --git a/src/libumskt/confid/confid.cpp b/src/libumskt/confid/confid.cpp index 2d64708..fbb6b1b 100644 --- a/src/libumskt/confid/confid.cpp +++ b/src/libumskt/confid/confid.cpp @@ -82,19 +82,18 @@ void ConfirmationID::setFlagVersion(unsigned int flagVersion) ConfirmationID::flagVersion = flagVersion; } - int ConfirmationID::calculateCheckDigit(int pid) { - unsigned int i = 0, j = 0, k = 0; - for (j = pid; j; i += k) - { - k = j % 10; - j /= 10; - } - return ((10 * pid) - (i % 7)) + 7; + unsigned int i = 0, j = 0, k = 0; + for (j = pid; j; i += k) + { + k = j % 10; + j /= 10; + } + return ((10 * pid) - (i % 7)) + 7; } -void ConfirmationID::decode_iid_new_version(unsigned char* iid, unsigned char* hwid, int* version) +void ConfirmationID::decode_iid_new_version(unsigned char *iid, unsigned char *hwid, int *version) { QWORD buffer[5]; for (int i = 0; i < 5; i++) @@ -113,15 +112,15 @@ void ConfirmationID::decode_iid_new_version(unsigned char* iid, unsigned char* h *version = buffer[0] & 7; } -void ConfirmationID::Mix(unsigned char* buffer, size_t bufSize, const unsigned char* key, size_t keySize) +void ConfirmationID::Mix(unsigned char *buffer, size_t bufSize, const unsigned char *key, size_t keySize) { - unsigned char sha1_input[64], sha1_result[20]; - size_t half = bufSize / 2; + unsigned char sha1_input[64], sha1_result[20]; + size_t half = bufSize / 2; - //assert(half <= sizeof(sha1_result) && half + keySize <= sizeof(sha1_input) - 9); - for (int external_counter = 0; external_counter < 4; external_counter++) + // assert(half <= sizeof(sha1_result) && half + keySize <= sizeof(sha1_input) - 9); + for (int external_counter = 0; external_counter < 4; external_counter++) { - memset(sha1_input, 0, sizeof(sha1_input)); + memset(sha1_input, 0, sizeof(sha1_input)); if (isXPBrand) { @@ -145,30 +144,30 @@ void ConfirmationID::Mix(unsigned char* buffer, size_t bufSize, const unsigned c SHA1(sha1_input, sizeof(sha1_input), sha1_result); - for (size_t i = half & ~3; i < half; i++) + for (size_t i = half & ~3; i < half; i++) { sha1_result[i] = sha1_result[i + 4 - (half & 3)]; } - for (size_t i = 0; i < half; i++) + for (size_t i = 0; i < half; i++) { - unsigned char tmp = buffer[i + half]; - buffer[i + half] = buffer[i] ^ sha1_result[i]; - buffer[i] = tmp; - } - } + unsigned char tmp = buffer[i + half]; + buffer[i + half] = buffer[i] ^ sha1_result[i]; + buffer[i] = tmp; + } + } } -void ConfirmationID::Unmix(unsigned char* buffer, size_t bufSize, const unsigned char key[4], size_t keySize) +void ConfirmationID::Unmix(unsigned char *buffer, size_t bufSize, const unsigned char key[4], size_t keySize) { - unsigned char sha1_input[64]; - unsigned char sha1_result[20]; - size_t half = bufSize / 2; - //assert(half <= sizeof(sha1_result) && half + keySize <= sizeof(sha1_input) - 9); + unsigned char sha1_input[64]; + unsigned char sha1_result[20]; + size_t half = bufSize / 2; + // assert(half <= sizeof(sha1_result) && half + keySize <= sizeof(sha1_input) - 9); - for (int external_counter = 0; external_counter < 4; external_counter++) + for (int external_counter = 0; external_counter < 4; external_counter++) { - memset(sha1_input, 0, sizeof(sha1_input)); + memset(sha1_input, 0, sizeof(sha1_input)); if (isXPBrand) { @@ -188,116 +187,117 @@ void ConfirmationID::Unmix(unsigned char* buffer, size_t bufSize, const unsigned sha1_input[sizeof(sha1_input) - 2] = (1 + half + keySize) * 8 / 0x100; } - SHA1(sha1_input, sizeof(sha1_input), sha1_result); + SHA1(sha1_input, sizeof(sha1_input), sha1_result); - for (size_t i = half & ~3; i < half; i++) + for (size_t i = half & ~3; i < half; i++) { sha1_result[i] = sha1_result[i + 4 - (half & 3)]; } - for (size_t i = 0; i < half; i++) + for (size_t i = 0; i < half; i++) { - unsigned char tmp = buffer[i]; - buffer[i] = buffer[i + half] ^ sha1_result[i]; - buffer[i + half] = tmp; - } - } + unsigned char tmp = buffer[i]; + buffer[i] = buffer[i + half] ^ sha1_result[i]; + buffer[i + half] = tmp; + } + } } -int ConfirmationID::Generate(const char* installation_id_str, char confirmation_id[49], std::string productid) +int ConfirmationID::Generate(const char *installation_id_str, char confirmation_id[49], std::string productid) { - int version; - unsigned char hardwareID[8]; - unsigned char installation_id[19]; // 10**45 < 256**19 + int version; + unsigned char hardwareID[8]; + unsigned char installation_id[19]; // 10**45 < 256**19 unsigned char productID[4]; - size_t installation_id_len = 0; - const char* pid = installation_id_str; + size_t installation_id_len = 0; + const char *pid = installation_id_str; - size_t count = 0, totalCount = 0; - unsigned check = 0; + size_t count = 0, totalCount = 0; + unsigned check = 0; - size_t i; + size_t i; - for (; *pid; pid++) + for (; *pid; pid++) { - if (*pid == ' ' || *pid == '-') + if (*pid == ' ' || *pid == '-') { continue; } - int d = *pid - '0'; + int d = *pid - '0'; - if (d < 0 || d > 9) + if (d < 0 || d > 9) { return ERR_INVALID_CHARACTER; } - if (count == 5 || p[1] == 0) + if (count == 5 || p[1] == 0) { - if (!count) + if (!count) { return (totalCount == 45) ? ERR_TOO_LARGE : ERR_TOO_SHORT; } - if (d != check % 7) + if (d != check % 7) { return (count < 5) ? ERR_TOO_SHORT : ERR_INVALID_CHECK_DIGIT; } - check = 0; - count = 0; - continue; - } + check = 0; + count = 0; + continue; + } - check += (count % 2 ? d * 2 : d); - count++; + check += (count % 2 ? d * 2 : d); + count++; - totalCount++; - if (totalCount > 45) + totalCount++; + if (totalCount > 45) { return ERR_TOO_LARGE; } - unsigned char carry = d; - for (i = 0; i < installation_id_len; i++) + unsigned char carry = d; + for (i = 0; i < installation_id_len; i++) { - unsigned x = installation_id[i] * 10 + carry; - installation_id[i] = x & 0xFF; - carry = x >> 8; - } + unsigned x = installation_id[i] * 10 + carry; + installation_id[i] = x & 0xFF; + carry = x >> 8; + } - if (carry) + if (carry) { - assert(installation_id_len < sizeof(installation_id)); - installation_id[installation_id_len++] = carry; - } - } + assert(installation_id_len < sizeof(installation_id)); + installation_id[installation_id_len++] = carry; + } + } - if (totalCount != 41 && totalCount < 45) + if (totalCount != 41 && totalCount < 45) { return ERR_TOO_SHORT; } - for (; installation_id_len < sizeof(installation_id); installation_id_len++) + for (; installation_id_len < sizeof(installation_id); installation_id_len++) { installation_id[installation_id_len] = 0; } - Unmix(installation_id, totalCount == 41 ? 17 : 19, iid_key, 4); + Unmix(installation_id, totalCount == 41 ? 17 : 19, iid_key, 4); - if (installation_id[18] >= 0x10) + if (installation_id[18] >= 0x10) { return ERR_UNKNOWN_VERSION; } #pragma pack(push, 1) - struct { - QWORD HardwareID; - QWORD ProductIDLow; - unsigned char ProductIDHigh; - unsigned short KeySHA1; - } parsed; + struct + { + QWORD HardwareID; + QWORD ProductIDLow; + unsigned char ProductIDHigh; + unsigned short KeySHA1; + } parsed; #pragma pack(pop) if (isXPBrand) @@ -306,7 +306,7 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_ productID[0] = parsed.ProductIDLow & ((1 << 17) - 1); productID[1] = (parsed.ProductIDLow >> 17) & ((1 << 10) - 1); productID[2] = (parsed.ProductIDLow >> 27) & ((1 << 24) - 1); - version = (parsed.ProductIDLow >> 51) & 15; + version = (parsed.ProductIDLow >> 51) & 15; productID[3] = (parsed.ProductIDLow >> 55) | (parsed.ProductIDHigh << 9); if (flagVersion == 0) @@ -331,9 +331,9 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_ } memcpy(&parsed, hardwareID, 8); - productID[0] = stoi(productid.substr(0,5)); + productID[0] = stoi(productid.substr(0, 5)); - std::string channelid = productid.substr(6,3); + std::string channelid = productid.substr(6, 3); char *p = &channelid[0]; for (; *p; p++) { @@ -342,38 +342,40 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_ if (strcmp(&channelid[0], "OEM") == 0) { - productID[1] = stoi(productid.substr(12,3)); - productID[2] = (stoi(productid.substr(15,1)) * 100000) + stoi(productid.substr(18,5)); + productID[1] = stoi(productid.substr(12, 3)); + productID[2] = (stoi(productid.substr(15, 1)) * 100000) + stoi(productid.substr(18, 5)); productID[2] = calculateCheckDigit(productID[2]); - productID[3] = ((stoi(productid.substr(10,2))) * 1000) + productID[3]; + productID[3] = ((stoi(productid.substr(10, 2))) * 1000) + productID[3]; } else { - productID[1] = stoi(productid.substr(6,3)); - productID[2] = stoi(productid.substr(10,7)); - productID[3] = stoi(productid.substr(18,5)); + productID[1] = stoi(productid.substr(6, 3)); + productID[2] = stoi(productid.substr(10, 7)); + productID[3] = stoi(productid.substr(18, 5)); } - //fmt::print("ProductID: {}-{}-{}-{} \n", productID[0], productID[1], productID[2], productID[3]); + // fmt::print("ProductID: {}-{}-{}-{} \n", productID[0], productID[1], productID[2], productID[3]); } - unsigned char keybuf[16]; - memcpy(keybuf, &parsed.HardwareID, 8); + unsigned char keybuf[16]; + memcpy(keybuf, &parsed.HardwareID, 8); - QWORD productIdMixed = (QWORD)productID[0] << 41 | (QWORD)productID[1] << 58 | (QWORD)productID[2] << 17 | productID[3]; - memcpy(keybuf + 8, &productIdMixed, 8); + QWORD productIdMixed = + (QWORD)productID[0] << 41 | (QWORD)productID[1] << 58 | (QWORD)productID[2] << 17 | productID[3]; + memcpy(keybuf + 8, &productIdMixed, 8); - TDivisor d; - unsigned char attempt; + TDivisor d; + unsigned char attempt; union { unsigned char buffer[14]; - struct { + struct + { QWORD lo; QWORD hi; }; } ulowhi; - for (attempt = 0; attempt <= 0x80; attempt++) + for (attempt = 0; attempt <= 0x80; attempt++) { ulowhi.lo = this->u[0]; ulowhi.hi = this->u[1]; @@ -387,122 +389,123 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_ ulowhi.buffer[6] = attempt; } - Mix(ulowhi.buffer, 14, keybuf, 16); - QWORD x2 = residue->ui128_quotient_mod(ulowhi.lo, ulowhi.hi); - QWORD x1 = ulowhi.lo - x2 * MOD; - x2++; + Mix(ulowhi.buffer, 14, keybuf, 16); + QWORD x2 = residue->ui128_quotient_mod(ulowhi.lo, ulowhi.hi); + QWORD x1 = ulowhi.lo - x2 * MOD; + x2++; - d.u[0] = residue->sub(residue->mul(x1, x1), residue->mul(NON_RESIDUE, residue->mul(x2, x2))); - d.u[1] = residue->add(x1, x1); - if (divisor->find_divisor_v(&d)) + d.u[0] = residue->sub(residue->mul(x1, x1), residue->mul(NON_RESIDUE, residue->mul(x2, x2))); + d.u[1] = residue->add(x1, x1); + if (divisor->find_divisor_v(&d)) { break; } - } + } - if (attempt > 0x80) + if (attempt > 0x80) { return ERR_UNLUCKY; } divisor->mul128(&d, u[0], u[1], &d); - union { - struct { - QWORD encoded_lo, encoded_hi; - }; - struct { - uint32_t encoded[4]; - }; - } e; + union { + struct + { + QWORD encoded_lo, encoded_hi; + }; + struct + { + uint32_t encoded[4]; + }; + } e; - if (d.u[0] == BAD) + if (d.u[0] == BAD) { - // we can not get the zero divisor, actually... - e.encoded_lo = residue->__umul128(MOD + 2, MOD, &e.encoded_hi); - } + // we can not get the zero divisor, actually... + e.encoded_lo = residue->__umul128(MOD + 2, MOD, &e.encoded_hi); + } else if (d.u[1] == BAD) { - // O(1/MOD) chance - //encoded = (unsigned __int128)(MOD + 1) * d.u[0] + MOD; // * MOD + d.u[0] is fine too - e.encoded_lo = residue->__umul128(MOD + 1, d.u[0], &e.encoded_hi); - e.encoded_lo += MOD; - e.encoded_hi += (e.encoded_lo < MOD); - } + // O(1/MOD) chance + // encoded = (unsigned __int128)(MOD + 1) * d.u[0] + MOD; // * MOD + d.u[0] is fine too + e.encoded_lo = residue->__umul128(MOD + 1, d.u[0], &e.encoded_hi); + e.encoded_lo += MOD; + e.encoded_hi += (e.encoded_lo < MOD); + } else { - QWORD x1 = (d.u[1] % 2 ? d.u[1] + MOD : d.u[1]) / 2; - QWORD x2sqr = residue->sub(residue->mul(x1, x1), d.u[0]); - QWORD x2 = residue->sqrt(x2sqr); + QWORD x1 = (d.u[1] % 2 ? d.u[1] + MOD : d.u[1]) / 2; + QWORD x2sqr = residue->sub(residue->mul(x1, x1), d.u[0]); + QWORD x2 = residue->sqrt(x2sqr); if (x2 == BAD) { - x2 = residue->sqrt(residue->mul(x2sqr, residue->inv(NON_RESIDUE))); - assert(x2 != BAD); - e.encoded_lo = residue->__umul128(MOD + 1, MOD + x2, &e.encoded_hi); - e.encoded_lo += x1; - e.encoded_hi += (e.encoded_lo < x1); - } + x2 = residue->sqrt(residue->mul(x2sqr, residue->inv(NON_RESIDUE))); + assert(x2 != BAD); + e.encoded_lo = residue->__umul128(MOD + 1, MOD + x2, &e.encoded_hi); + e.encoded_lo += x1; + e.encoded_hi += (e.encoded_lo < x1); + } else { - // points (-x1+x2, v(-x1+x2)) and (-x1-x2, v(-x1-x2)) - QWORD x1a = residue->sub(x1, x2); - QWORD y1 = residue->sub(d.v[0], residue->mul(d.v[1], x1a)); - QWORD x2a = residue->add(x1, x2); - QWORD y2 = residue->sub(d.v[0], residue->mul(d.v[1], x2a)); - if (x1a > x2a) + // points (-x1+x2, v(-x1+x2)) and (-x1-x2, v(-x1-x2)) + QWORD x1a = residue->sub(x1, x2); + QWORD y1 = residue->sub(d.v[0], residue->mul(d.v[1], x1a)); + QWORD x2a = residue->add(x1, x2); + QWORD y2 = residue->sub(d.v[0], residue->mul(d.v[1], x2a)); + if (x1a > x2a) { - QWORD tmp = x1a; - x1a = x2a; - x2a = tmp; - } + QWORD tmp = x1a; + x1a = x2a; + x2a = tmp; + } if ((y1 ^ y2) & 1) { - QWORD tmp = x1a; - x1a = x2a; - x2a = tmp; - } + QWORD tmp = x1a; + x1a = x2a; + x2a = tmp; + } - e.encoded_lo = residue->__umul128(MOD + 1, x1a, &e.encoded_hi); - e.encoded_lo += x2a; - e.encoded_hi += (e.encoded_lo < x2a); + e.encoded_lo = residue->__umul128(MOD + 1, x1a, &e.encoded_hi); + e.encoded_lo += x2a; + e.encoded_hi += (e.encoded_lo < x2a); + } + } - } - } - - unsigned char decimal[35]; - for (i = 0; i < 35; i++) + unsigned char decimal[35]; + for (i = 0; i < 35; i++) { - unsigned c = e.encoded[3] % 10; - e.encoded[3] /= 10; - unsigned c2 = ((QWORD)c << 32 | e.encoded[2]) % 10; - e.encoded[2] = ((QWORD)c << 32 | e.encoded[2]) / 10; - unsigned c3 = ((QWORD)c2 << 32 | e.encoded[1]) % 10; - e.encoded[1] = ((QWORD)c2 << 32 | e.encoded[1]) / 10; - unsigned c4 = ((QWORD)c3 << 32 | e.encoded[0]) % 10; - e.encoded[0] = ((QWORD)c3 << 32 | e.encoded[0]) / 10; - decimal[34 - i] = c4; - } + unsigned c = e.encoded[3] % 10; + e.encoded[3] /= 10; + unsigned c2 = ((QWORD)c << 32 | e.encoded[2]) % 10; + e.encoded[2] = ((QWORD)c << 32 | e.encoded[2]) / 10; + unsigned c3 = ((QWORD)c2 << 32 | e.encoded[1]) % 10; + e.encoded[1] = ((QWORD)c2 << 32 | e.encoded[1]) / 10; + unsigned c4 = ((QWORD)c3 << 32 | e.encoded[0]) % 10; + e.encoded[0] = ((QWORD)c3 << 32 | e.encoded[0]) / 10; + decimal[34 - i] = c4; + } - assert(e.encoded[0] == 0 && e.encoded[1] == 0 && e.encoded[2] == 0 && e.encoded[3] == 0); - char* q = confirmation_id; - for (i = 0; i < 7; i++) + assert(e.encoded[0] == 0 && e.encoded[1] == 0 && e.encoded[2] == 0 && e.encoded[3] == 0); + char *q = confirmation_id; + for (i = 0; i < 7; i++) { - if (i) + if (i) { *q++ = '-'; } - unsigned char* p = decimal + i*5; - q[0] = p[0] + '0'; - q[1] = p[1] + '0'; - q[2] = p[2] + '0'; - q[3] = p[3] + '0'; - q[4] = p[4] + '0'; - q[5] = ((p[0]+p[1]*2+p[2]+p[3]*2+p[4]) % 7) + '0'; - q += 6; - } - *q++ = 0; - return 0; + unsigned char *p = decimal + i * 5; + q[0] = p[0] + '0'; + q[1] = p[1] + '0'; + q[2] = p[2] + '0'; + q[3] = p[3] + '0'; + q[4] = p[4] + '0'; + q[5] = ((p[0] + p[1] * 2 + p[2] + p[3] * 2 + p[4]) % 7) + '0'; + q += 6; + } + *q++ = 0; + return 0; } diff --git a/src/libumskt/confid/confid.h b/src/libumskt/confid/confid.h index c46fef3..09d933b 100644 --- a/src/libumskt/confid/confid.h +++ b/src/libumskt/confid/confid.h @@ -26,49 +26,53 @@ #include "../libumskt.h" // Confirmation ID generator constants -enum CONFIRMATION_ID_STATUS { - SUCCESS = 0, - ERR_TOO_SHORT = 1, - ERR_TOO_LARGE = 2, - ERR_INVALID_CHARACTER = 3, +enum CONFIRMATION_ID_STATUS +{ + SUCCESS = 0, + ERR_TOO_SHORT = 1, + ERR_TOO_LARGE = 2, + ERR_INVALID_CHARACTER = 3, ERR_INVALID_CHECK_DIGIT = 4, - ERR_UNKNOWN_VERSION = 5, - ERR_UNLUCKY = 6 + ERR_UNKNOWN_VERSION = 5, + ERR_UNLUCKY = 6 }; #define BAD 0xFFFFFFFFFFFFFFFFull -typedef struct { +typedef struct +{ QWORD u[2]; QWORD v[2]; } TDivisor; -enum ACTIVATION_ALGORITHM { - WINDOWS = 0, - OFFICE_XP = 1, - OFFICE_2K3 = 2, - OFFICE_2K7 = 3, - PLUS_DME = 4, +enum ACTIVATION_ALGORITHM +{ + WINDOWS = 0, + OFFICE_XP = 1, + OFFICE_2K3 = 2, + OFFICE_2K7 = 3, + PLUS_DME = 4, }; -EXPORT class ConfirmationID { +EXPORT class ConfirmationID +{ QWORD MOD = 0, NON_RESIDUE = 0; - QWORD f[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; - QWORD p[4] = { 0x0, 0x0, 0x0, 0x0 }; - QWORD u[2] = { 0x0, 0x0 }; + QWORD f[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + QWORD p[4] = {0x0, 0x0, 0x0, 0x0}; + QWORD u[2] = {0x0, 0x0}; - unsigned char iid_key[4] = { 0x0, 0x0, 0x0, 0x0}; + unsigned char iid_key[4] = {0x0, 0x0, 0x0, 0x0}; BOOL isOffice = false, isXPBrand = false; unsigned flagVersion = 0; -public: + + public: void setFlagVersion(unsigned int flagVersion); -private: - + private: int calculateCheckDigit(int pid); - void decode_iid_new_version(unsigned char* iid, unsigned char* hwid, int* version); - void Mix(unsigned char* buffer, size_t bufSize, const unsigned char* key, size_t keySize); - void Unmix(unsigned char* buffer, size_t bufSize, const unsigned char* key, size_t keySize); + void decode_iid_new_version(unsigned char *iid, unsigned char *hwid, int *version); + void Mix(unsigned char *buffer, size_t bufSize, const unsigned char *key, size_t keySize); + void Unmix(unsigned char *buffer, size_t bufSize, const unsigned char *key, size_t keySize); friend class Residue; Residue *residue; @@ -79,8 +83,8 @@ private: friend class Divisor; Divisor *divisor; -public: - int Generate(const char* installation_id_str, char confirmation_id[49], std::string productid); + public: + int Generate(const char *installation_id_str, char confirmation_id[49], std::string productid); void setMod(QWORD mod); void setNonResidue(QWORD nonResidue); @@ -91,28 +95,32 @@ public: void setIsOffice(BOOL isOffice); void setIsXPBrand(BOOL isXpBrand); - ConfirmationID() { + ConfirmationID() + { residue = new Residue(this); polynomial = new Polynomial(this); divisor = new Divisor(this); } - ~ConfirmationID() { + ~ConfirmationID() + { delete residue, polynomial, divisor; } }; -class Residue { +class Residue +{ ConfirmationID *parent; -public: - explicit Residue(ConfirmationID *in) { + public: + explicit Residue(ConfirmationID *in) + { parent = in; } QWORD add(QWORD x, QWORD y); QWORD sub(QWORD x, QWORD y); - QWORD __umul128(QWORD a, QWORD b, QWORD* hi); + QWORD __umul128(QWORD a, QWORD b, QWORD *hi); QWORD ui128_quotient_mod(QWORD lo, QWORD hi); QWORD mul(QWORD x, QWORD y); QWORD pow(QWORD x, QWORD y); @@ -121,33 +129,37 @@ public: QWORD sqrt(QWORD what); }; -class Polynomial { +class Polynomial +{ ConfirmationID *parent; -public: - explicit Polynomial(ConfirmationID *in) { + public: + explicit Polynomial(ConfirmationID *in) + { parent = in; } int mul(int adeg, const QWORD a[], int bdeg, const QWORD b[], int resultprevdeg, QWORD result[]); - int div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD* quotient); - void xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], int* pgcddeg, QWORD gcd[3], int* pmult1deg, QWORD mult1[3], int* pmult2deg, QWORD mult2[3]); - int u2poly(const TDivisor* src, QWORD polyu[3], QWORD polyv[2]); + int div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD *quotient); + void xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], int *pgcddeg, QWORD gcd[3], int *pmult1deg, + QWORD mult1[3], int *pmult2deg, QWORD mult2[3]); + int u2poly(const TDivisor *src, QWORD polyu[3], QWORD polyv[2]); }; -class Divisor { +class Divisor +{ ConfirmationID *parent; -public: - explicit Divisor(ConfirmationID *in) { + public: + explicit Divisor(ConfirmationID *in) + { parent = in; } - int find_divisor_v(TDivisor* d); - void add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst); - void mul(const TDivisor* src, QWORD mult, TDivisor* dst); - void mul128(const TDivisor* src, QWORD mult_lo, QWORD mult_hi, TDivisor* dst); + int find_divisor_v(TDivisor *d); + void add(const TDivisor *src1, const TDivisor *src2, TDivisor *dst); + void mul(const TDivisor *src, QWORD mult, TDivisor *dst); + void mul128(const TDivisor *src, QWORD mult_lo, QWORD mult_hi, TDivisor *dst); }; - -#endif //UMSKT_CONFID_H +#endif // UMSKT_CONFID_H diff --git a/src/libumskt/confid/divisor.cpp b/src/libumskt/confid/divisor.cpp index 93de732..8709a6e 100644 --- a/src/libumskt/confid/divisor.cpp +++ b/src/libumskt/confid/divisor.cpp @@ -22,7 +22,7 @@ #include "confid.h" -int Divisor::find_divisor_v(TDivisor* d) +int Divisor::find_divisor_v(TDivisor *d) { // u | v^2 - f // u = u0 + u1*x + x^2 @@ -36,7 +36,7 @@ int Divisor::find_divisor_v(TDivisor* d) const QWORD u0 = d->u[0]; const QWORD u1 = d->u[1]; - for (int j = 4; j--; ) + for (int j = 4; j--;) { f2[j] = parent->residue->sub(f2[j], parent->residue->mul(u0, f2[j + 2])); f2[j + 1] = parent->residue->sub(f2[j + 1], parent->residue->mul(u1, f2[j + 2])); @@ -63,11 +63,12 @@ int Divisor::find_divisor_v(TDivisor* d) if (f1 == 0) { // impossible - //printf("bad f(), double root detected\n"); + // printf("bad f(), double root detected\n"); } return 0; } - QWORD sqr = parent->residue->mul(parent->residue->mul(f1, f1), parent->residue->inv(parent->residue->add(coeff1, coeff1))); + QWORD sqr = parent->residue->mul(parent->residue->mul(f1, f1), + parent->residue->inv(parent->residue->add(coeff1, coeff1))); v1 = parent->residue->sqrt(sqr); if (v1 == BAD) { @@ -76,7 +77,9 @@ int Divisor::find_divisor_v(TDivisor* d) } else { - QWORD d = parent->residue->add(parent->residue->mul(f0, f0), parent->residue->mul(f1, parent->residue->sub(parent->residue->mul(f1, u0), parent->residue->mul(f0, u1)))); + QWORD d = parent->residue->add( + parent->residue->mul(f0, f0), + parent->residue->mul(f1, parent->residue->sub(parent->residue->mul(f1, u0), parent->residue->mul(f0, u1)))); d = parent->residue->sqrt(d); if (d == BAD) { @@ -98,14 +101,15 @@ int Divisor::find_divisor_v(TDivisor* d) } } - QWORD v0 = parent->residue->mul(parent->residue->add(f1, parent->residue->mul(u1, parent->residue->mul(v1, v1))), parent->residue->inv(parent->residue->add(v1, v1))); + QWORD v0 = parent->residue->mul(parent->residue->add(f1, parent->residue->mul(u1, parent->residue->mul(v1, v1))), + parent->residue->inv(parent->residue->add(v1, v1))); d->v[0] = v0; d->v[1] = v1; return 1; } -int Divisor::u2poly(const TDivisor* src, QWORD polyu[3], QWORD polyv[2]) +int Divisor::u2poly(const TDivisor *src, QWORD polyu[3], QWORD polyv[2]) { if (src->u[1] != BAD) { @@ -132,7 +136,7 @@ int Divisor::u2poly(const TDivisor* src, QWORD polyu[3], QWORD polyv[2]) return 0; } -void Divisor::add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst) +void Divisor::add(const TDivisor *src1, const TDivisor *src2, TDivisor *dst) { QWORD u1[3], u2[3], v1[2], v2[2]; int u1deg = u2poly(src1, u1, v1); @@ -198,21 +202,25 @@ void Divisor::add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst) if (ddeg > 0) { - assert(udeg >= 2*ddeg); + assert(udeg >= 2 * ddeg); QWORD udiv[5]; - parent->polynomial->div_monic(udeg, u, ddeg, d, udiv); udeg -= ddeg; - parent->polynomial->div_monic(udeg, udiv, ddeg, d, u); udeg -= ddeg; + parent->polynomial->div_monic(udeg, u, ddeg, d, udiv); + udeg -= ddeg; + parent->polynomial->div_monic(udeg, udiv, ddeg, d, u); + udeg -= ddeg; if (vdeg >= 0) { assert(vdeg >= ddeg); - parent->polynomial->div_monic(vdeg, v, ddeg, d, udiv); vdeg -= ddeg; + parent->polynomial->div_monic(vdeg, v, ddeg, d, udiv); + vdeg -= ddeg; memcpy(v, udiv, (vdeg + 1) * sizeof(v[0])); } } vdeg = parent->polynomial->div_monic(vdeg, v, udeg, u, NULL); - while (udeg > 2) { + while (udeg > 2) + { assert(udeg <= 4); assert(vdeg <= 3); // u' = monic((f-v^2)/u), v'=-v mod u' @@ -280,7 +288,7 @@ void Divisor::add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst) #define divisor_double(src, dst) add(src, src, dst) -void Divisor::mul(const TDivisor* src, QWORD mult, TDivisor* dst) +void Divisor::mul(const TDivisor *src, QWORD mult, TDivisor *dst) { if (mult == 0) { @@ -309,7 +317,7 @@ void Divisor::mul(const TDivisor* src, QWORD mult, TDivisor* dst) } } -void Divisor::mul128(const TDivisor* src, QWORD mult_lo, QWORD mult_hi, TDivisor* dst) +void Divisor::mul128(const TDivisor *src, QWORD mult_lo, QWORD mult_hi, TDivisor *dst) { if (mult_lo == 0 && mult_hi == 0) { @@ -325,7 +333,8 @@ void Divisor::mul128(const TDivisor* src, QWORD mult_lo, QWORD mult_hi, TDivisor { divisor_double(&cur, &cur); mult_lo >>= 1; - if (mult_hi & 1) { + if (mult_hi & 1) + { mult_lo |= (1ULL << 63); } mult_hi >>= 1; diff --git a/src/libumskt/confid/polynomial.cpp b/src/libumskt/confid/polynomial.cpp index 18a6bae..cf3b888 100644 --- a/src/libumskt/confid/polynomial.cpp +++ b/src/libumskt/confid/polynomial.cpp @@ -55,7 +55,7 @@ int Polynomial::mul(int adeg, const QWORD a[], int bdeg, const QWORD b[], int re return resultprevdeg; } -int Polynomial::div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD* quotient) +int Polynomial::div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD *quotient) { assert(bdeg >= 0); assert(b[bdeg] == 1); @@ -84,25 +84,32 @@ int Polynomial::div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD* return i; } -void Polynomial::xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], int* pgcddeg, QWORD gcd[3], int* pmult1deg, QWORD mult1[3], int* pmult2deg, QWORD mult2[3]) +void Polynomial::xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], int *pgcddeg, QWORD gcd[3], + int *pmult1deg, QWORD mult1[3], int *pmult2deg, QWORD mult2[3]) { int sdeg = -1; QWORD s[3] = {0, 0, 0}; int mult1deg = 0; - mult1[0] = 1; mult1[1] = 0; mult1[2] = 0; + mult1[0] = 1; + mult1[1] = 0; + mult1[2] = 0; int tdeg = 0; QWORD t[3] = {1, 0, 0}; int mult2deg = -1; - mult2[0] = 0; mult2[1] = 0; mult2[2] = 0; + mult2[0] = 0; + mult2[1] = 0; + mult2[2] = 0; int rdeg = bdeg; QWORD r[3] = {b[0], b[1], b[2]}; int gcddeg = adeg; - gcd[0] = a[0]; gcd[1] = a[1]; gcd[2] = a[2]; + gcd[0] = a[0]; + gcd[1] = a[1]; + gcd[2] = a[2]; // s*u1 + t*u2 = r // mult1*u1 + mult2*u2 = gcd @@ -112,19 +119,43 @@ void Polynomial::xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], in { unsigned tmp; int tmpi; - tmp = rdeg; rdeg = gcddeg; gcddeg = tmp; - tmpi = sdeg; sdeg = mult1deg; mult1deg = tmpi; - tmpi = tdeg; tdeg = mult2deg; mult2deg = tmpi; + tmp = rdeg; + rdeg = gcddeg; + gcddeg = tmp; + tmpi = sdeg; + sdeg = mult1deg; + mult1deg = tmpi; + tmpi = tdeg; + tdeg = mult2deg; + mult2deg = tmpi; QWORD tmp2; - tmp2 = r[0]; r[0] = gcd[0]; gcd[0] = tmp2; - tmp2 = r[1]; r[1] = gcd[1]; gcd[1] = tmp2; - tmp2 = r[2]; r[2] = gcd[2]; gcd[2] = tmp2; - tmp2 = s[0]; s[0] = mult1[0]; mult1[0] = tmp2; - tmp2 = s[1]; s[1] = mult1[1]; mult1[1] = tmp2; - tmp2 = s[2]; s[2] = mult1[2]; mult1[2] = tmp2; - tmp2 = t[0]; t[0] = mult2[0]; mult2[0] = tmp2; - tmp2 = t[1]; t[1] = mult2[1]; mult2[1] = tmp2; - tmp2 = t[2]; t[2] = mult2[2]; mult2[2] = tmp2; + tmp2 = r[0]; + r[0] = gcd[0]; + gcd[0] = tmp2; + tmp2 = r[1]; + r[1] = gcd[1]; + gcd[1] = tmp2; + tmp2 = r[2]; + r[2] = gcd[2]; + gcd[2] = tmp2; + tmp2 = s[0]; + s[0] = mult1[0]; + mult1[0] = tmp2; + tmp2 = s[1]; + s[1] = mult1[1]; + mult1[1] = tmp2; + tmp2 = s[2]; + s[2] = mult1[2]; + mult1[2] = tmp2; + tmp2 = t[0]; + t[0] = mult2[0]; + mult2[0] = tmp2; + tmp2 = t[1]; + t[1] = mult2[1]; + mult2[1] = tmp2; + tmp2 = t[2]; + t[2] = mult2[2]; + mult2[2] = tmp2; continue; } diff --git a/src/libumskt/confid/residue.cpp b/src/libumskt/confid/residue.cpp index 5adc259..70ecd97 100644 --- a/src/libumskt/confid/residue.cpp +++ b/src/libumskt/confid/residue.cpp @@ -24,11 +24,11 @@ #if defined(__x86_64__) || defined(_M_AMD64) || defined(__aarch64__) || (defined(__arm64__) && defined(__APPLE__)) #ifdef __GNUC__ -inline QWORD Residue::__umul128(QWORD a, QWORD b, QWORD* hi) +inline QWORD Residue::__umul128(QWORD a, QWORD b, QWORD *hi) { OWORD r = (OWORD)a * (OWORD)b; *hi = r >> 64; - return (QWORD) r; + return (QWORD)r; } #else #define __umul128 _umul128 @@ -44,9 +44,9 @@ inline QWORD Residue::__umul128(QWORD multiplier, QWORD multiplicand, QWORD *pro QWORD c = multiplicand >> 32; QWORD d = multiplicand & 0xFFFFFFFF; - //QWORD ac = a * c; + // QWORD ac = a * c; QWORD ad = a * d; - //QWORD bc = b * c; + // QWORD bc = b * c; QWORD bd = b * d; QWORD adbc = ad + (b * c); @@ -91,7 +91,7 @@ QWORD Residue::ui128_quotient_mod(QWORD lo, QWORD hi) QWORD Residue::mul(QWORD x, QWORD y) { -// * ceil(2**170/MOD) = 0x2d351 c6d04f8b|604fa6a1 c6346a87 for (p-1)*(p-1) max + // * ceil(2**170/MOD) = 0x2d351 c6d04f8b|604fa6a1 c6346a87 for (p-1)*(p-1) max QWORD hi; QWORD lo = __umul128(x, y, &hi); QWORD quotient = ui128_quotient_mod(lo, hi); @@ -128,7 +128,7 @@ QWORD Residue::pow(QWORD x, QWORD y) QWORD Residue::add(QWORD x, QWORD y) { QWORD z = x + y; - //z = z - (z >= MOD ? MOD : 0); + // z = z - (z >= MOD ? MOD : 0); if (z >= parent->MOD) { z -= parent->MOD; @@ -139,7 +139,7 @@ QWORD Residue::add(QWORD x, QWORD y) QWORD Residue::sub(QWORD x, QWORD y) { QWORD z = x - y; - //z += (x < y ? MOD : 0); + // z += (x < y ? MOD : 0); if (x < y) { z += parent->MOD; @@ -149,15 +149,20 @@ QWORD Residue::sub(QWORD x, QWORD y) QWORD Residue::inverse(QWORD u, QWORD v) { - //assert(u); + // assert(u); int64_t tmp; int64_t xu = 1, xv = 0; QWORD v0 = v; while (u > 1) { - QWORD d = v / u; QWORD remainder = v % u; - tmp = u; u = remainder; v = tmp; - tmp = xu; xu = xv - d * xu; xv = tmp; + QWORD d = v / u; + QWORD remainder = v % u; + tmp = u; + u = remainder; + v = tmp; + tmp = xu; + xu = xv - d * xu; + xv = tmp; } xu += (xu < 0 ? v0 : 0); return xu; @@ -190,15 +195,15 @@ QWORD Residue::sqrt(QWORD what) x = pow(what, (q - 1) / 2); b = mul(mul(what, x), x); x = mul(what, x); - while (b != 1) { + while (b != 1) + { QWORD m = 0, b2 = b; do { m++; b2 = mul(b2, b2); - } - while (b2 != 1); + } while (b2 != 1); if (m == r) { @@ -214,7 +219,7 @@ QWORD Residue::sqrt(QWORD what) if (mul(x, x) != what) { - //printf("internal error in sqrt\n"); + // printf("internal error in sqrt\n"); return BAD; } diff --git a/src/libumskt/debugoutput.cpp b/src/libumskt/debugoutput.cpp index 3d0b95a..824d12f 100644 --- a/src/libumskt/debugoutput.cpp +++ b/src/libumskt/debugoutput.cpp @@ -22,14 +22,13 @@ #include "libumskt.h" - #ifdef _WIN32 -std::FILE* UMSKT::debug = std::fopen("NUL:", "w"); +std::FILE *UMSKT::debug = std::fopen("NUL:", "w"); #else -std::FILE* UMSKT::debug = std::fopen("/dev/null", "w"); +std::FILE *UMSKT::debug = std::fopen("/dev/null", "w"); #endif - -void UMSKT::setDebugOutput(std::FILE* input) { +void UMSKT::setDebugOutput(std::FILE *input) +{ debug = input; } diff --git a/src/libumskt/libumskt.cpp b/src/libumskt/libumskt.cpp index 6293c14..608b22b 100644 --- a/src/libumskt/libumskt.cpp +++ b/src/libumskt/libumskt.cpp @@ -22,39 +22,53 @@ #include "libumskt.h" #include "confid/confid.h" -#include "pidgen3/PIDGEN3.h" +#include "pidgen2/PIDGEN2.h" #include "pidgen3/BINK1998.h" #include "pidgen3/BINK2002.h" -#include "pidgen2/PIDGEN2.h" +#include "pidgen3/PIDGEN3.h" -FNEXPORT int ConfirmationID_Generate(const char* installation_id_str, char confirmation_id[49], int mode, std::string productid) { +FNEXPORT int ConfirmationID_Generate(const char *installation_id_str, char confirmation_id[49], int mode, + std::string productid) +{ return ConfirmationID::Generate(installation_id_str, confirmation_id, mode, productid); } -FNEXPORT EC_GROUP* PIDGEN3_initializeEllipticCurve(char* pSel, char* aSel, char* bSel, char* generatorXSel, char* generatorYSel, char* publicKeyXSel, char* publicKeyYSel, EC_POINT *&genPoint, EC_POINT *&pubPoint) { - return PIDGEN3::initializeEllipticCurve(pSel, aSel, bSel, generatorXSel, generatorYSel, publicKeyXSel, publicKeyYSel, genPoint, pubPoint); +FNEXPORT EC_GROUP *PIDGEN3_initializeEllipticCurve(char *pSel, char *aSel, char *bSel, char *generatorXSel, + char *generatorYSel, char *publicKeyXSel, char *publicKeyYSel, + EC_POINT *&genPoint, EC_POINT *&pubPoint) +{ + return PIDGEN3::initializeEllipticCurve(pSel, aSel, bSel, generatorXSel, generatorYSel, publicKeyXSel, + publicKeyYSel, genPoint, pubPoint); } -FNEXPORT bool PIDGEN3_BINK1998_Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&pKey)[25]) { +FNEXPORT bool PIDGEN3_BINK1998_Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&pKey)[25]) +{ return PIDGEN3::BINK1998::Verify(eCurve, basePoint, publicKey, pKey); } -FNEXPORT void PIDGEN3_BINK1998_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, DWORD pSerial, BOOL pUpgrade,char (&pKey)[25]) { +FNEXPORT void PIDGEN3_BINK1998_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, + DWORD pSerial, BOOL pUpgrade, char (&pKey)[25]) +{ return PIDGEN3::BINK1998::Generate(eCurve, basePoint, genOrder, privateKey, pSerial, pUpgrade, pKey); } -FNEXPORT bool PIDGEN3_BINK2002_Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&cdKey)[25]) { +FNEXPORT bool PIDGEN3_BINK2002_Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&cdKey)[25]) +{ return PIDGEN3::BINK2002::Verify(eCurve, basePoint, publicKey, cdKey); } -FNEXPORT void PIDGEN3_BINK2002_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, DWORD pChannelID, DWORD pAuthInfo, BOOL pUpgrade, char (&pKey)[25]) { +FNEXPORT void PIDGEN3_BINK2002_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, + DWORD pChannelID, DWORD pAuthInfo, BOOL pUpgrade, char (&pKey)[25]) +{ return PIDGEN3::BINK2002::Generate(eCurve, basePoint, genOrder, privateKey, pChannelID, pAuthInfo, pUpgrade, pKey); } -FNEXPORT int PIDGEN2_GenerateRetail(char* channelID, char* &keyout) { +FNEXPORT int PIDGEN2_GenerateRetail(char *channelID, char *&keyout) +{ return PIDGEN2::GenerateRetail(channelID, keyout); } -FNEXPORT int PIDGEN2_GenerateOEM(char* year, char* day, char* oem, char* keyout) { +FNEXPORT int PIDGEN2_GenerateOEM(char *year, char *day, char *oem, char *keyout) +{ return PIDGEN2::GenerateOEM(year, day, oem, keyout); } diff --git a/src/libumskt/libumskt.h b/src/libumskt/libumskt.h index e01d768..1631dbd 100644 --- a/src/libumskt/libumskt.h +++ b/src/libumskt/libumskt.h @@ -25,49 +25,49 @@ #include "../typedefs.h" -#include #include #include +#include #include #include -#include #include #include +#include #include #include // Algorithm macros -#define PK_LENGTH 25 -#define NULL_TERMINATOR 1 +#define PK_LENGTH 25 +#define NULL_TERMINATOR 1 -#define FIELD_BITS 384 -#define FIELD_BYTES 48 -#define FIELD_BITS_2003 512 -#define FIELD_BYTES_2003 64 +#define FIELD_BITS 384 +#define FIELD_BYTES 48 +#define FIELD_BITS_2003 512 +#define FIELD_BYTES_2003 64 -#define SHA_MSG_LENGTH_XP (4 + 2 * FIELD_BYTES) -#define SHA_MSG_LENGTH_2003 (3 + 2 * FIELD_BYTES_2003) +#define SHA_MSG_LENGTH_XP (4 + 2 * FIELD_BYTES) +#define SHA_MSG_LENGTH_2003 (3 + 2 * FIELD_BYTES_2003) -#define NEXTSNBITS(field, n, offset) (((QWORD)(field) >> (offset)) & ((1ULL << (n)) - 1)) -#define FIRSTNBITS(field, n) NEXTSNBITS((field), (n), 0) +#define NEXTSNBITS(field, n, offset) (((QWORD)(field) >> (offset)) & ((1ULL << (n)) - 1)) +#define FIRSTNBITS(field, n) NEXTSNBITS((field), (n), 0) -#define HIBYTES(field, bytes) NEXTSNBITS((QWORD)(field), ((bytes) * 8), ((bytes) * 8)) -#define LOBYTES(field, bytes) FIRSTNBITS((QWORD)(field), ((bytes) * 8)) +#define HIBYTES(field, bytes) NEXTSNBITS((QWORD)(field), ((bytes)*8), ((bytes)*8)) +#define LOBYTES(field, bytes) FIRSTNBITS((QWORD)(field), ((bytes)*8)) -#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24) -#define BITMASK(n) ((1ULL << (n)) - 1) +#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24) +#define BITMASK(n) ((1ULL << (n)) - 1) -class UMSKT { -public: - static std::FILE* debug; +class UMSKT +{ + public: + static std::FILE *debug; class PIDGEN2; class PIDGEN3; class ConfigurationID; - static void setDebugOutput(std::FILE* input); + static void setDebugOutput(std::FILE *input); }; - -#endif //UMSKT_LIBUMSKT_H +#endif // UMSKT_LIBUMSKT_H diff --git a/src/libumskt/pidgen2/PIDGEN2.cpp b/src/libumskt/pidgen2/PIDGEN2.cpp index 6a3b59e..e9c26c8 100644 --- a/src/libumskt/pidgen2/PIDGEN2.cpp +++ b/src/libumskt/pidgen2/PIDGEN2.cpp @@ -22,12 +22,15 @@ #include "PIDGEN2.h" -const char* channelIDBlacklist [7] = {"333", "444", "555", "666", "777", "888", "999"}; -const char* validYears[8] = { "95", "96", "97", "98", "99", "00", "01", "02"}; +const char *channelIDBlacklist[7] = {"333", "444", "555", "666", "777", "888", "999"}; +const char *validYears[8] = {"95", "96", "97", "98", "99", "00", "01", "02"}; -bool PIDGEN2::isNumericString(char* input) { - for(int i = 0; i < strlen(input); i++) { - if (input[i] < '0' || input[i] > '9') { +bool PIDGEN2::isNumericString(char *input) +{ + for (int i = 0; i < strlen(input); i++) + { + if (input[i] < '0' || input[i] > '9') + { return false; } } @@ -35,27 +38,34 @@ bool PIDGEN2::isNumericString(char* input) { return true; } -int PIDGEN2::addDigits(char* input) { +int PIDGEN2::addDigits(char *input) +{ int output = 0; - if (!isNumericString(input)) { + if (!isNumericString(input)) + { return -1; } - for(int i = 0; i < strlen(input); i++) { + for (int i = 0; i < strlen(input); i++) + { output += input[i] - '0'; } return output; } -bool PIDGEN2::isValidChannelID(char* channelID) { - if (strlen(channelID) > 3) { +bool PIDGEN2::isValidChannelID(char *channelID) +{ + if (strlen(channelID) > 3) + { return false; } - for (int i = 0; i <= 6; i++) { - if (strcmp(channelID, channelIDBlacklist[i]) != 0) { + for (int i = 0; i <= 6; i++) + { + if (strcmp(channelID, channelIDBlacklist[i]) != 0) + { return false; } } @@ -63,13 +73,17 @@ bool PIDGEN2::isValidChannelID(char* channelID) { return true; } -bool PIDGEN2::isValidOEMID(char* OEMID) { - if (!isNumericString(OEMID)) { +bool PIDGEN2::isValidOEMID(char *OEMID) +{ + if (!isNumericString(OEMID)) + { return false; } - if (strlen(OEMID) > 5) { - if (OEMID[0] != '0' || OEMID[1] != '0') { + if (strlen(OEMID) > 5) + { + if (OEMID[0] != '0' || OEMID[1] != '0') + { return false; } } @@ -79,52 +93,65 @@ bool PIDGEN2::isValidOEMID(char* OEMID) { return (mod % 21 == 0); } -bool PIDGEN2::isValidYear(char* year) { - for (int i = 0; i <= 7; i++) { - if (year == validYears[i]) { +bool PIDGEN2::isValidYear(char *year) +{ + for (int i = 0; i <= 7; i++) + { + if (year == validYears[i]) + { return false; } } return true; } -bool PIDGEN2::isValidDay(char* day) { - if (!isNumericString(day)) { +bool PIDGEN2::isValidDay(char *day) +{ + if (!isNumericString(day)) + { return false; } int iDay = std::stoi(day); - if (iDay == 0 || iDay >= 365) { + if (iDay == 0 || iDay >= 365) + { return false; } return true; } -bool PIDGEN2::isValidRetailProductID(char* productID) { +bool PIDGEN2::isValidRetailProductID(char *productID) +{ return true; } -int PIDGEN2::GenerateRetail(char* channelID, char* &keyout) { - if (!isValidChannelID(channelID)) { +int PIDGEN2::GenerateRetail(char *channelID, char *&keyout) +{ + if (!isValidChannelID(channelID)) + { return 1; } return 0; } -int PIDGEN2::GenerateOEM(char* year, char* day, char* oem, char* &keyout) { - if (!isValidOEMID(oem)) { +int PIDGEN2::GenerateOEM(char *year, char *day, char *oem, char *&keyout) +{ + if (!isValidOEMID(oem)) + { int mod = addDigits(oem); mod += mod % 21; strcpy(oem, fmt::format("{:07d}", mod).c_str()); } - if (!isValidYear(year)) { + if (!isValidYear(year)) + { strcpy(year, validYears[0]); } - if (!isValidDay(day)) { + if (!isValidDay(day)) + { int iday = std::stoi(day); iday = (iday + 1) % 365; } diff --git a/src/libumskt/pidgen2/PIDGEN2.h b/src/libumskt/pidgen2/PIDGEN2.h index a59ae4c..7c4bd0d 100644 --- a/src/libumskt/pidgen2/PIDGEN2.h +++ b/src/libumskt/pidgen2/PIDGEN2.h @@ -25,17 +25,18 @@ #include "../libumskt.h" -EXPORT class PIDGEN2 { -public: - static bool isNumericString(char* input); - static bool isValidChannelID(char* channelID); - static bool isValidOEMID(char* OEMID); - static bool isValidYear(char* year); - static bool isValidDay(char* day); - static bool isValidRetailProductID(char* productID); - static int addDigits(char* input); - static int GenerateRetail(char* channelID, char* &keyout); - static int GenerateOEM(char* year, char* day, char* oem, char* &keyout); +EXPORT class PIDGEN2 +{ + public: + static bool isNumericString(char *input); + static bool isValidChannelID(char *channelID); + static bool isValidOEMID(char *OEMID); + static bool isValidYear(char *year); + static bool isValidDay(char *day); + static bool isValidRetailProductID(char *productID); + static int addDigits(char *input); + static int GenerateRetail(char *channelID, char *&keyout); + static int GenerateOEM(char *year, char *day, char *oem, char *&keyout); }; -#endif //UMSKT_PIDGEN2_H +#endif // UMSKT_PIDGEN2_H diff --git a/src/libumskt/pidgen3/BINK1998.cpp b/src/libumskt/pidgen3/BINK1998.cpp index dc40cbb..a1bfbd4 100644 --- a/src/libumskt/pidgen3/BINK1998.cpp +++ b/src/libumskt/pidgen3/BINK1998.cpp @@ -30,13 +30,8 @@ #include "BINK1998.h" /* Unpacks a Windows XP-like Product Key. */ -void PIDGEN3::BINK1998::Unpack( - QWORD (&pRaw)[2], - BOOL &pUpgrade, - DWORD &pSerial, - DWORD &pHash, - QWORD &pSignature -) { +void PIDGEN3::BINK1998::Unpack(QWORD (&pRaw)[2], BOOL &pUpgrade, DWORD &pSerial, DWORD &pHash, QWORD &pSignature) +{ // We're assuming that the quantity of information within the product key is at most 114 bits. // log2(24^25) = 114. @@ -54,13 +49,8 @@ void PIDGEN3::BINK1998::Unpack( } /* Packs a Windows XP-like Product Key. */ -void PIDGEN3::BINK1998::Pack( - QWORD (&pRaw)[2], - BOOL pUpgrade, - DWORD pSerial, - DWORD pHash, - QWORD pSignature -) { +void PIDGEN3::BINK1998::Pack(QWORD (&pRaw)[2], BOOL pUpgrade, DWORD pSerial, DWORD pHash, QWORD pSignature) +{ // The quantity of information the key provides is 114 bits. // We're storing it in 2 64-bit quad-words with 14 trailing bits. // 64 * 2 = 128 @@ -71,22 +61,15 @@ void PIDGEN3::BINK1998::Pack( } /* Verifies a Windows XP-like Product Key. */ -bool PIDGEN3::BINK1998::Verify( - EC_GROUP *eCurve, - EC_POINT *basePoint, - EC_POINT *publicKey, - char (&pKey)[25] -) { +bool PIDGEN3::BINK1998::Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&pKey)[25]) +{ BN_CTX *numContext = BN_CTX_new(); - QWORD pRaw[2]{}, - pSignature; + QWORD pRaw[2]{}, pSignature; - DWORD pData, - pSerial, - pHash; + DWORD pData, pSerial, pHash; - BOOL pUpgrade; + BOOL pUpgrade; // Convert Base24 CD-key to bytecode. PIDGEN3::unbase24((BYTE *)pRaw, pKey); @@ -119,9 +102,7 @@ bool PIDGEN3::BINK1998::Verify( */ BIGNUM *e = BN_lebin2bn((BYTE *)&pHash, sizeof(pHash), nullptr), - *s = BN_lebin2bn((BYTE *)&pSignature, sizeof(pSignature), nullptr), - *x = BN_new(), - *y = BN_new(); + *s = BN_lebin2bn((BYTE *)&pSignature, sizeof(pSignature), nullptr), *x = BN_new(), *y = BN_new(); // Create 2 points on the elliptic curve. EC_POINT *t = EC_POINT_new(eCurve); @@ -139,10 +120,7 @@ bool PIDGEN3::BINK1998::Verify( // x = P.x; y = P.y; EC_POINT_get_affine_coordinates(eCurve, p, x, y, numContext); - BYTE msgDigest[SHA_DIGEST_LENGTH]{}, - msgBuffer[SHA_MSG_LENGTH_XP]{}, - xBin[FIELD_BYTES]{}, - yBin[FIELD_BYTES]{}; + BYTE msgDigest[SHA_DIGEST_LENGTH]{}, msgBuffer[SHA_MSG_LENGTH_XP]{}, xBin[FIELD_BYTES]{}, yBin[FIELD_BYTES]{}; // Convert resulting point coordinates to bytes. BN_bn2lebin(x, xBin, FIELD_BYTES); @@ -175,29 +153,20 @@ bool PIDGEN3::BINK1998::Verify( } /* Generates a Windows XP-like Product Key. */ -void PIDGEN3::BINK1998::Generate( - EC_GROUP *eCurve, - EC_POINT *basePoint, - BIGNUM *genOrder, - BIGNUM *privateKey, - DWORD pSerial, - BOOL pUpgrade, - char (&pKey)[25] -) { +void PIDGEN3::BINK1998::Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, + DWORD pSerial, BOOL pUpgrade, char (&pKey)[25]) +{ BN_CTX *numContext = BN_CTX_new(); - BIGNUM *c = BN_new(), - *s = BN_new(), - *x = BN_new(), - *y = BN_new(); + BIGNUM *c = BN_new(), *s = BN_new(), *x = BN_new(), *y = BN_new(); - QWORD pRaw[2]{}, - pSignature = 0; + QWORD pRaw[2]{}, pSignature = 0; // Data segment of the RPK. DWORD pData = pSerial << 1 | pUpgrade; - do { + do + { EC_POINT *r = EC_POINT_new(eCurve); // Generate a random number c consisting of 384 bits without any constraints. @@ -211,10 +180,7 @@ void PIDGEN3::BINK1998::Generate( // x = R.x; y = R.y; EC_POINT_get_affine_coordinates(eCurve, r, x, y, numContext); - BYTE msgDigest[SHA_DIGEST_LENGTH]{}, - msgBuffer[SHA_MSG_LENGTH_XP]{}, - xBin[FIELD_BYTES]{}, - yBin[FIELD_BYTES]{}; + BYTE msgDigest[SHA_DIGEST_LENGTH]{}, msgBuffer[SHA_MSG_LENGTH_XP]{}, xBin[FIELD_BYTES]{}, yBin[FIELD_BYTES]{}; // Convert coordinates to bytes. BN_bn2lebin(x, xBin, FIELD_BYTES); diff --git a/src/libumskt/pidgen3/BINK1998.h b/src/libumskt/pidgen3/BINK1998.h index 0260f60..65bf702 100644 --- a/src/libumskt/pidgen3/BINK1998.h +++ b/src/libumskt/pidgen3/BINK1998.h @@ -25,40 +25,17 @@ #include "PIDGEN3.h" -EXPORT class PIDGEN3::BINK1998 { -public: - static void Unpack( - QWORD (&pRaw)[2], - BOOL &pUpgrade, - DWORD &pSerial, - DWORD &pHash, - QWORD &pSignature - ); +EXPORT class PIDGEN3::BINK1998 +{ + public: + static void Unpack(QWORD (&pRaw)[2], BOOL &pUpgrade, DWORD &pSerial, DWORD &pHash, QWORD &pSignature); - static void Pack( - QWORD (&pRaw)[2], - BOOL pUpgrade, - DWORD pSerial, - DWORD pHash, - QWORD pSignature - ); + static void Pack(QWORD (&pRaw)[2], BOOL pUpgrade, DWORD pSerial, DWORD pHash, QWORD pSignature); - static bool Verify( - EC_GROUP *eCurve, - EC_POINT *basePoint, - EC_POINT *publicKey, - char (&pKey)[25] - ); + static bool Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&pKey)[25]); - static void Generate( - EC_GROUP *eCurve, - EC_POINT *basePoint, - BIGNUM *genOrder, - BIGNUM *privateKey, - DWORD pSerial, - BOOL pUpgrade, - char (&pKey)[25] - ); + static void Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, DWORD pSerial, + BOOL pUpgrade, char (&pKey)[25]); }; -#endif //UMSKT_BINK1998_H +#endif // UMSKT_BINK1998_H diff --git a/src/libumskt/pidgen3/BINK2002.cpp b/src/libumskt/pidgen3/BINK2002.cpp index 2246f97..ca87563 100644 --- a/src/libumskt/pidgen3/BINK2002.cpp +++ b/src/libumskt/pidgen3/BINK2002.cpp @@ -30,14 +30,9 @@ #include "BINK2002.h" /* Unpacks a Windows Server 2003-like Product Key. */ -void PIDGEN3::BINK2002::Unpack( - QWORD (&pRaw)[2], - BOOL &pUpgrade, - DWORD &pChannelID, - DWORD &pHash, - QWORD &pSignature, - DWORD &pAuthInfo -) { +void PIDGEN3::BINK2002::Unpack(QWORD (&pRaw)[2], BOOL &pUpgrade, DWORD &pChannelID, DWORD &pHash, QWORD &pSignature, + DWORD &pAuthInfo) +{ // We're assuming that the quantity of information within the product key is at most 114 bits. // log2(24^25) = 114. @@ -60,37 +55,24 @@ void PIDGEN3::BINK2002::Unpack( } /* Packs a Windows Server 2003-like Product Key. */ -void PIDGEN3::BINK2002::Pack( - QWORD (&pRaw)[2], - BOOL pUpgrade, - DWORD pChannelID, - DWORD pHash, - QWORD pSignature, - DWORD pAuthInfo -) { +void PIDGEN3::BINK2002::Pack(QWORD (&pRaw)[2], BOOL pUpgrade, DWORD pChannelID, DWORD pHash, QWORD pSignature, + DWORD pAuthInfo) +{ // AuthInfo [113..104] <- Signature [103..42] <- Hash [41..11] <- Channel ID [10..1] <- Upgrade [0] pRaw[0] = FIRSTNBITS(pSignature, 22) << 42 | (QWORD)pHash << 11 | pChannelID << 1 | pUpgrade; pRaw[1] = FIRSTNBITS(pAuthInfo, 10) << 40 | NEXTSNBITS(pSignature, 40, 22); } /* Verifies a Windows Server 2003-like Product Key. */ -bool PIDGEN3::BINK2002::Verify( - EC_GROUP *eCurve, - EC_POINT *basePoint, - EC_POINT *publicKey, - char (&cdKey)[25] -) { +bool PIDGEN3::BINK2002::Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&cdKey)[25]) +{ BN_CTX *context = BN_CTX_new(); - QWORD bKey[2]{}, - pSignature = 0; + QWORD bKey[2]{}, pSignature = 0; - DWORD pData, - pChannelID, - pHash, - pAuthInfo; + DWORD pData, pChannelID, pHash, pAuthInfo; - BOOL pUpgrade; + BOOL pUpgrade; // Convert Base24 CD-key to bytecode. unbase24((BYTE *)bKey, cdKey); @@ -108,10 +90,8 @@ bool PIDGEN3::BINK2002::Verify( fmt::print(UMSKT::debug, " AuthInfo: 0x{:08x}\n", pAuthInfo); fmt::print(UMSKT::debug, "\n"); - BYTE msgDigest[SHA_DIGEST_LENGTH]{}, - msgBuffer[SHA_MSG_LENGTH_2003]{}, - xBin[FIELD_BYTES_2003]{}, - yBin[FIELD_BYTES_2003]{}; + BYTE msgDigest[SHA_DIGEST_LENGTH]{}, msgBuffer[SHA_MSG_LENGTH_2003]{}, xBin[FIELD_BYTES_2003]{}, + yBin[FIELD_BYTES_2003]{}; // Assemble the first SHA message. msgBuffer[0x00] = 0x5D; @@ -130,7 +110,8 @@ bool PIDGEN3::BINK2002::Verify( SHA1(msgBuffer, 11, msgDigest); // Translate the byte digest into a 64-bit integer - this is our computed intermediate signature. - // As the signature is only 62 bits long at most, we have to truncate it by shifting the high DWORD right 2 bits (per spec). + // As the signature is only 62 bits long at most, we have to truncate it by shifting the high DWORD right 2 bits + // (per spec). QWORD iSignature = NEXTSNBITS(BYDWORD(&msgDigest[4]), 30, 2) << 32 | BYDWORD(msgDigest); /* @@ -149,9 +130,7 @@ bool PIDGEN3::BINK2002::Verify( */ BIGNUM *e = BN_lebin2bn((BYTE *)&iSignature, sizeof(iSignature), nullptr), - *s = BN_lebin2bn((BYTE *)&pSignature, sizeof(pSignature), nullptr), - *x = BN_new(), - *y = BN_new(); + *s = BN_lebin2bn((BYTE *)&pSignature, sizeof(pSignature), nullptr), *x = BN_new(), *y = BN_new(); // Create 2 points on the elliptic curve. EC_POINT *p = EC_POINT_new(eCurve); @@ -206,33 +185,22 @@ bool PIDGEN3::BINK2002::Verify( } /* Generates a Windows Server 2003-like Product Key. */ -void PIDGEN3::BINK2002::Generate( - EC_GROUP *eCurve, - EC_POINT *basePoint, - BIGNUM *genOrder, - BIGNUM *privateKey, - DWORD pChannelID, - DWORD pAuthInfo, - BOOL pUpgrade, - char (&pKey)[25] -) { +void PIDGEN3::BINK2002::Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, + DWORD pChannelID, DWORD pAuthInfo, BOOL pUpgrade, char (&pKey)[25]) +{ BN_CTX *numContext = BN_CTX_new(); - BIGNUM *c = BN_new(), - *e = BN_new(), - *s = BN_new(), - *x = BN_new(), - *y = BN_new(); + BIGNUM *c = BN_new(), *e = BN_new(), *s = BN_new(), *x = BN_new(), *y = BN_new(); - QWORD pRaw[2]{}, - pSignature = 0; + QWORD pRaw[2]{}, pSignature = 0; // Data segment of the RPK. DWORD pData = pChannelID << 1 | pUpgrade; BOOL noSquare; - do { + do + { EC_POINT *r = EC_POINT_new(eCurve); // Generate a random number c consisting of 512 bits without any constraints. @@ -245,10 +213,8 @@ void PIDGEN3::BINK2002::Generate( // x = R.x; y = R.y; EC_POINT_get_affine_coordinates(eCurve, r, x, y, numContext); - BYTE msgDigest[SHA_DIGEST_LENGTH]{}, - msgBuffer[SHA_MSG_LENGTH_2003]{}, - xBin[FIELD_BYTES_2003]{}, - yBin[FIELD_BYTES_2003]{}; + BYTE msgDigest[SHA_DIGEST_LENGTH]{}, msgBuffer[SHA_MSG_LENGTH_2003]{}, xBin[FIELD_BYTES_2003]{}, + yBin[FIELD_BYTES_2003]{}; // Convert resulting point coordinates to bytes. BN_bn2lebin(x, xBin, FIELD_BYTES_2003); @@ -286,7 +252,8 @@ void PIDGEN3::BINK2002::Generate( SHA1(msgBuffer, 11, msgDigest); // Translate the byte digest into a 64-bit integer - this is our computed intermediate signature. - // As the signature is only 62 bits long at most, we have to truncate it by shifting the high DWORD right 2 bits (per spec). + // As the signature is only 62 bits long at most, we have to truncate it by shifting the high DWORD right 2 + // bits (per spec). QWORD iSignature = NEXTSNBITS(BYDWORD(&msgDigest[4]), 30, 2) << 32 | BYDWORD(msgDigest); BN_lebin2bn((BYTE *)&iSignature, sizeof(iSignature), e); @@ -346,9 +313,11 @@ void PIDGEN3::BINK2002::Generate( // If s is odd, add order to it. // The order is a prime, so it can't be even. if (BN_is_odd(s)) + { // s = -ek + √((ek)² + 4c) + n BN_add(s, s, genOrder); + } // s /= 2 (s >>= 1) BN_rshift1(s, s); diff --git a/src/libumskt/pidgen3/BINK2002.h b/src/libumskt/pidgen3/BINK2002.h index 75a0e7d..9391b87 100644 --- a/src/libumskt/pidgen3/BINK2002.h +++ b/src/libumskt/pidgen3/BINK2002.h @@ -25,43 +25,18 @@ #include "PIDGEN3.h" -EXPORT class PIDGEN3::BINK2002 { -public: - static void Unpack( - QWORD (&pRaw)[2], - BOOL &pUpgrade, - DWORD &pChannelID, - DWORD &pHash, - QWORD &pSignature, - DWORD &pAuthInfo - ); +EXPORT class PIDGEN3::BINK2002 +{ + public: + static void Unpack(QWORD (&pRaw)[2], BOOL &pUpgrade, DWORD &pChannelID, DWORD &pHash, QWORD &pSignature, + DWORD &pAuthInfo); - static void Pack( - QWORD (&pRaw)[2], - BOOL pUpgrade, - DWORD pChannelID, - DWORD pHash, - QWORD pSignature, - DWORD pAuthInfo - ); + static void Pack(QWORD (&pRaw)[2], BOOL pUpgrade, DWORD pChannelID, DWORD pHash, QWORD pSignature, DWORD pAuthInfo); - static bool Verify( - EC_GROUP *eCurve, - EC_POINT *basePoint, - EC_POINT *publicKey, - char (&cdKey)[25] - ); + static bool Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&cdKey)[25]); - static void Generate( - EC_GROUP *eCurve, - EC_POINT *basePoint, - BIGNUM *genOrder, - BIGNUM *privateKey, - DWORD pChannelID, - DWORD pAuthInfo, - BOOL pUpgrade, - char (&pKey)[25] - ); + static void Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, DWORD pChannelID, + DWORD pAuthInfo, BOOL pUpgrade, char (&pKey)[25]); }; -#endif //UMSKT_BINK2002_H +#endif // UMSKT_BINK2002_H diff --git a/src/libumskt/pidgen3/PIDGEN3.h b/src/libumskt/pidgen3/PIDGEN3.h index 6f77de1..e396c47 100644 --- a/src/libumskt/pidgen3/PIDGEN3.h +++ b/src/libumskt/pidgen3/PIDGEN3.h @@ -25,25 +25,20 @@ #include "../libumskt.h" -class PIDGEN3 { -public: +class PIDGEN3 +{ + public: class BINK1998; class BINK2002; // util.cpp - static int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); // Hello OpenSSL developers, please tell me, where is this function at? + static int BN_bn2lebin(const BIGNUM *a, unsigned char *to, + int tolen); // Hello OpenSSL developers, please tell me, where is this function at? static void endian(BYTE *data, int length); - static EC_GROUP* initializeEllipticCurve( - std::string pSel, - std::string aSel, - std::string bSel, - std::string generatorXSel, - std::string generatorYSel, - std::string publicKeyXSel, - std::string publicKeyYSel, - EC_POINT *&genPoint, - EC_POINT *&pubPoint - ); + static EC_GROUP *initializeEllipticCurve(std::string pSel, std::string aSel, std::string bSel, + std::string generatorXSel, std::string generatorYSel, + std::string publicKeyXSel, std::string publicKeyYSel, EC_POINT *&genPoint, + EC_POINT *&pubPoint); // key.cpp static constexpr char pKeyCharset[] = "BCDFGHJKMPQRTVWXY2346789"; @@ -51,4 +46,4 @@ public: static void base24(char *cdKey, BYTE *byteSeq); }; -#endif //UMSKT_PIDGEN3_H +#endif // UMSKT_PIDGEN3_H diff --git a/src/libumskt/pidgen3/key.cpp b/src/libumskt/pidgen3/key.cpp index 636669c..7cb2a8a 100644 --- a/src/libumskt/pidgen3/key.cpp +++ b/src/libumskt/pidgen3/key.cpp @@ -23,16 +23,20 @@ #include "PIDGEN3.h" /* Converts from CD-key to a byte sequence. */ -void PIDGEN3::unbase24(BYTE *byteSeq, const char *cdKey) { +void PIDGEN3::unbase24(BYTE *byteSeq, const char *cdKey) +{ BYTE pDecodedKey[PK_LENGTH + NULL_TERMINATOR]{}; BIGNUM *y = BN_new(); BN_zero(y); // Remove dashes from the CD-key and put it into a Base24 byte array. - for (int i = 0, k = 0; i < strlen(cdKey) && k < PK_LENGTH; i++) { - for (int j = 0; j < 24; j++) { - if (cdKey[i] != '-' && cdKey[i] == pKeyCharset[j]) { + for (int i = 0, k = 0; i < strlen(cdKey) && k < PK_LENGTH; i++) + { + for (int j = 0; j < 24; j++) + { + if (cdKey[i] != '-' && cdKey[i] == pKeyCharset[j]) + { pDecodedKey[k++] = j; break; } @@ -43,7 +47,8 @@ void PIDGEN3::unbase24(BYTE *byteSeq, const char *cdKey) { memset(byteSeq, 0, 16); // Calculate the weighed sum of byte array elements. - for (int i = 0; i < PK_LENGTH; i++) { + for (int i = 0; i < PK_LENGTH; i++) + { BN_mul_word(y, PK_LENGTH - 1); BN_add_word(y, pDecodedKey[i]); } @@ -60,7 +65,8 @@ void PIDGEN3::unbase24(BYTE *byteSeq, const char *cdKey) { } /* Converts from byte sequence to the CD-key. */ -void PIDGEN3::base24(char *cdKey, BYTE *byteSeq) { +void PIDGEN3::base24(char *cdKey, BYTE *byteSeq) +{ BYTE rbyteSeq[16]; BIGNUM *z; @@ -70,7 +76,10 @@ void PIDGEN3::base24(char *cdKey, BYTE *byteSeq) { // Skip trailing zeroes and reverse y. int length; - for (length = 15; rbyteSeq[length] == 0; length--); + for (length = 15; rbyteSeq[length] == 0; length--) + { + ; + } endian(rbyteSeq, ++length); // Convert reversed byte sequence to BigNum z. @@ -80,7 +89,9 @@ void PIDGEN3::base24(char *cdKey, BYTE *byteSeq) { cdKey[25] = 0; for (int i = 24; i >= 0; i--) + { cdKey[i] = pKeyCharset[BN_div_word(z, 24)]; + } BN_free(z); } diff --git a/src/libumskt/pidgen3/util.cpp b/src/libumskt/pidgen3/util.cpp index 2255af5..38b81a4 100644 --- a/src/libumskt/pidgen3/util.cpp +++ b/src/libumskt/pidgen3/util.cpp @@ -22,14 +22,17 @@ #include "PIDGEN3.h" -int randomRange() { - return 4; // chosen by fair dice roll - // guaranteed to be random +int randomRange() +{ + return 4; // chosen by fair dice roll + // guaranteed to be random } /* Convert data between endianness types. */ -void PIDGEN3::endian(BYTE *data, int length) { - for (int i = 0; i < length / 2; i++) { +void PIDGEN3::endian(BYTE *data, int length) +{ + for (int i = 0; i < length / 2; i++) + { BYTE temp = data[i]; data[i] = data[length - i - 1]; data[length - i - 1] = temp; @@ -37,17 +40,11 @@ void PIDGEN3::endian(BYTE *data, int length) { } /* Initializes the elliptic curve. */ -EC_GROUP* PIDGEN3::initializeEllipticCurve( - const std::string pSel, - const std::string aSel, - const std::string bSel, - const std::string generatorXSel, - const std::string generatorYSel, - const std::string publicKeyXSel, - const std::string publicKeyYSel, - EC_POINT *&genPoint, - EC_POINT *&pubPoint -) { +EC_GROUP *PIDGEN3::initializeEllipticCurve(const std::string pSel, const std::string aSel, const std::string bSel, + const std::string generatorXSel, const std::string generatorYSel, + const std::string publicKeyXSel, const std::string publicKeyYSel, + EC_POINT *&genPoint, EC_POINT *&pubPoint) +{ // Initialize BIGNUM and BIGNUMCTX structures. // BIGNUM - Large numbers // BIGNUMCTX - Context large numbers (temporary) @@ -83,7 +80,8 @@ EC_GROUP* PIDGEN3::initializeEllipticCurve( /* Elliptic Curve calculations. */ // The group is defined via Fp = all integers [0; p - 1], where p is prime. - // The function EC_POINT_set_affine_coordinates() sets the x and y coordinates for the point p defined over the curve given in group. + // The function EC_POINT_set_affine_coordinates() sets the x and y coordinates for the point p defined over the + // curve given in group. EC_GROUP *eCurve = EC_GROUP_new_curve_GFp(p, a, b, context); // Create new point for the generator on the elliptic curve and set its coordinates to (genX; genY). @@ -94,7 +92,8 @@ EC_GROUP* PIDGEN3::initializeEllipticCurve( pubPoint = EC_POINT_new(eCurve); EC_POINT_set_affine_coordinates(eCurve, pubPoint, publicKeyX, publicKeyY, context); - // If generator and public key points are not on the elliptic curve, either the generator or the public key values are incorrect. + // If generator and public key points are not on the elliptic curve, either the generator or the public key values + // are incorrect. assert(EC_POINT_is_on_curve(eCurve, genPoint, context) == true); assert(EC_POINT_is_on_curve(eCurve, pubPoint, context) == true); @@ -111,14 +110,19 @@ EC_GROUP* PIDGEN3::initializeEllipticCurve( return eCurve; } -int PIDGEN3::BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) { +int PIDGEN3::BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) +{ if (a == nullptr || to == nullptr) + { return 0; + } int len = BN_bn2bin(a, to); if (len > tolen) + { return -1; + } // Choke point inside BN_bn2lebinpad: OpenSSL uses len instead of tolen. endian(to, tolen); diff --git a/src/main.cpp b/src/main.cpp index 31234b6..f3571c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,13 +20,15 @@ * @Maintainer Neo */ -#include "header.h" #include "cli.h" +#include "header.h" Options options; -int main(int argc, char *argv[]) { - if (!CLI::parseCommandLine(argc, argv, &options)) { +int main(int argc, char *argv[]) +{ + if (!CLI::parseCommandLine(argc, argv, &options)) + { fmt::print("error parsing command line options\n"); CLI::showHelp(argv); return !options.error ? 0 : 1; @@ -35,29 +37,31 @@ int main(int argc, char *argv[]) { json keys; int status = CLI::validateCommandLine(&options, argv, &keys); - if (status > 0) { + if (status > 0) + { return status; } CLI run(options, keys); - switch(options.applicationMode) { - case MODE_BINK1998_GENERATE: - return run.BINK1998Generate(); + switch (options.applicationMode) + { + case MODE_BINK1998_GENERATE: + return run.BINK1998Generate(); - case MODE_BINK2002_GENERATE: - return run.BINK2002Generate(); + case MODE_BINK2002_GENERATE: + return run.BINK2002Generate(); - case MODE_BINK1998_VALIDATE: - return run.BINK1998Validate(); + case MODE_BINK1998_VALIDATE: + return run.BINK1998Validate(); - case MODE_BINK2002_VALIDATE: - return run.BINK2002Validate(); + case MODE_BINK2002_VALIDATE: + return run.BINK2002Validate(); - case MODE_CONFIRMATION_ID: - return run.ConfirmationID(); + case MODE_CONFIRMATION_ID: + return run.ConfirmationID(); - default: - return 1; + default: + return 1; } } diff --git a/src/typedefs.h b/src/typedefs.h index b53787a..3adf14d 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -23,8 +23,8 @@ #ifndef UMSKT_TYPEDEFS_H #define UMSKT_TYPEDEFS_H -#include #include +#include #ifdef DEBUG #include @@ -46,8 +46,8 @@ #endif // Type definitions -typedef bool BOOL; -typedef uint8_t BYTE; +typedef bool BOOL; +typedef uint8_t BYTE; typedef uint16_t WORD; typedef uint32_t DWORD; typedef uint64_t QWORD; @@ -56,4 +56,4 @@ typedef uint64_t QWORD; typedef unsigned __int128 OWORD; #endif -#endif //UMSKT_TYPEDEFS_H +#endif // UMSKT_TYPEDEFS_H diff --git a/src/windows/dllmain.cpp b/src/windows/dllmain.cpp index 03d9ed3..e769ebd 100644 --- a/src/windows/dllmain.cpp +++ b/src/windows/dllmain.cpp @@ -21,23 +21,23 @@ */ #define WIN32_LEAN_AND_MEAN -#include #include "resource.h" +#include -BOOLEAN WINAPI DllMain( IN HINSTANCE hDllHandle, - IN DWORD nReason, - IN LPVOID Reserved ) { +BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle, IN DWORD nReason, IN LPVOID Reserved) +{ BOOLEAN bSuccess = TRUE; // Perform global initialization. - switch (nReason) { - case DLL_PROCESS_ATTACH: - // For optimization. - DisableThreadLibraryCalls(hDllHandle); - break; + switch (nReason) + { + case DLL_PROCESS_ATTACH: + // For optimization. + DisableThreadLibraryCalls(hDllHandle); + break; - case DLL_PROCESS_DETACH: - break; + case DLL_PROCESS_DETACH: + break; } return bSuccess; diff --git a/src/windows/resource.h b/src/windows/resource.h index 9d01308..af03788 100644 --- a/src/windows/resource.h +++ b/src/windows/resource.h @@ -24,15 +24,15 @@ // Microsoft Visual C++ generated include file. // Used by umskt.rc // -#define IDI_ICON1 101 +#define IDI_ICON1 101 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 #endif #endif