standardize using clang-format

This commit is contained in:
Neo-Desktop 2023-12-10 04:06:42 -08:00
parent 8cc691b72f
commit c0a4c76b54
25 changed files with 1155 additions and 826 deletions

216
.clang-format Normal file
View File

@ -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
...

View File

@ -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,97 +81,117 @@ 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];
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") {
}
else if (arg == "-u" || arg == "--upgrade")
{
options->upgrade = true;
} else if (arg == "-f" || arg == "--file") {
if (i == argc - 1) {
}
else if (arg == "-f" || arg == "--file")
{
if (i == argc - 1)
{
options->error = true;
break;
}
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;
}
@ -172,34 +199,52 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
options->instid = argv[i + 1];
options->applicationMode = MODE_CONFIRMATION_ID;
i++;
} else if (arg == "-m" || arg == "--mode") {
}
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];
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;
}
@ -207,53 +252,72 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
options->keyToCheck = argv[i + 1];
options->applicationMode = MODE_BINK1998_VALIDATE;
i++;
} else if (arg == "-N" || arg == "--nonewlines") {
}
else if (arg == "-N" || arg == "--nonewlines")
{
options->nonewlines = true;
} else {
}
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 {
}
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<std::string>().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
}
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),
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;
}
// 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;
@ -374,7 +454,8 @@ CLI::CLI(Options options, json keys) {
BN_dec2bn(&this->genOrder, this->keys["BINK"][this->BINKID]["n"].get<std::string>().c_str());
BN_dec2bn(&this->privateKey, this->keys["BINK"][this->BINKID]["priv"].get<std::string>().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<std::string>(),
eCurve = PIDGEN3::initializeEllipticCurve(this->keys["BINK"][this->BINKID]["p"].get<std::string>(),
this->keys["BINK"][this->BINKID]["a"].get<std::string>(),
this->keys["BINK"][this->BINKID]["b"].get<std::string>(),
this->keys["BINK"][this->BINKID]["g"]["x"].get<std::string>(),
this->keys["BINK"][this->BINKID]["g"]["y"].get<std::string>(),
this->keys["BINK"][this->BINKID]["pub"]["x"].get<std::string>(),
this->keys["BINK"][this->BINKID]["pub"]["y"].get<std::string>(),
this->genPoint,
this->pubPoint
);
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 */
// 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);
@ -429,7 +510,8 @@ int CLI::BINK1998Generate() {
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) {
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
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) {
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) {
auto confid = new class ConfirmationID();
int err = confid->Generate(this->options.instid.c_str(), confirmation_id, options.productid);
if (err == SUCCESS)
{
fmt::print(confirmation_id);
if (!this->options.nonewlines)
{
fmt::print("\n");
}
return 0;
}
switch (err)
{
case ERR_TOO_SHORT:
fmt::print("ERROR: Installation ID is too short.\n");
return 1;
case ERR_TOO_LARGE:
fmt::print("ERROR: Installation ID is too long.\n");
return 1;
case ERR_INVALID_CHARACTER:
fmt::print("ERROR: Invalid character in installation ID.\n");
return 1;
case ERR_INVALID_CHECK_DIGIT:
fmt::print("ERROR: Installation ID checksum failed. Please check that it is typed correctly.\n");
return 1;
case ERR_UNKNOWN_VERSION:
fmt::print("ERROR: Unknown installation ID version.\n");
return 1;
case ERR_UNLUCKY:
fmt::print("ERROR: Unable to generate valid confirmation ID.\n");
return 1;
case SUCCESS:
fmt::print(confirmation_id);
if (!this->options.nonewlines) {
fmt::print("\n");
}
return 0;
default:
fmt::print("Unknown error occurred during Confirmation ID generation: {}\n", err);
}
return 1;
}

View File

@ -27,16 +27,17 @@
#include <cmrc/cmrc.hpp>
#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,
@ -44,7 +45,8 @@ enum MODE {
MODE_BINK2002_VALIDATE = 4,
};
struct Options {
struct Options
{
std::string binkid;
std::string keysFilename;
std::string instid;
@ -65,7 +67,8 @@ struct Options {
ACTIVATION_ALGORITHM activationMode;
};
class CLI {
class CLI
{
Options options;
json keys;
const char *BINKID;

View File

@ -25,12 +25,12 @@
#include "typedefs.h"
#include <iostream>
#include <fstream>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <vector>
#include <fmt/core.h>
#include <nlohmann/json.hpp>

View File

@ -82,7 +82,6 @@ void ConfirmationID::setFlagVersion(unsigned int flagVersion)
ConfirmationID::flagVersion = flagVersion;
}
int ConfirmationID::calculateCheckDigit(int pid)
{
unsigned int i = 0, j = 0, k = 0;
@ -292,7 +291,8 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
}
#pragma pack(push, 1)
struct {
struct
{
QWORD HardwareID;
QWORD ProductIDLow;
unsigned char ProductIDHigh;
@ -359,7 +359,8 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
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];
QWORD productIdMixed =
(QWORD)productID[0] << 41 | (QWORD)productID[1] << 58 | (QWORD)productID[2] << 17 | productID[3];
memcpy(keybuf + 8, &productIdMixed, 8);
TDivisor d;
@ -367,7 +368,8 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
union {
unsigned char buffer[14];
struct {
struct
{
QWORD lo;
QWORD hi;
};
@ -408,10 +410,12 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
divisor->mul128(&d, u[0], u[1], &d);
union {
struct {
struct
{
QWORD encoded_lo, encoded_hi;
};
struct {
struct
{
uint32_t encoded[4];
};
} e;
@ -467,7 +471,6 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
e.encoded_lo = residue->__umul128(MOD + 1, x1a, &e.encoded_hi);
e.encoded_lo += x2a;
e.encoded_hi += (e.encoded_lo < x2a);
}
}

View File

@ -26,7 +26,8 @@
#include "../libumskt.h"
// Confirmation ID generator constants
enum CONFIRMATION_ID_STATUS {
enum CONFIRMATION_ID_STATUS
{
SUCCESS = 0,
ERR_TOO_SHORT = 1,
ERR_TOO_LARGE = 2,
@ -38,12 +39,14 @@ enum CONFIRMATION_ID_STATUS {
#define BAD 0xFFFFFFFFFFFFFFFFull
typedef struct {
typedef struct
{
QWORD u[2];
QWORD v[2];
} TDivisor;
enum ACTIVATION_ALGORITHM {
enum ACTIVATION_ALGORITHM
{
WINDOWS = 0,
OFFICE_XP = 1,
OFFICE_2K3 = 2,
@ -51,7 +54,8 @@ enum ACTIVATION_ALGORITHM {
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};
@ -60,11 +64,11 @@ EXPORT class ConfirmationID {
unsigned char iid_key[4] = {0x0, 0x0, 0x0, 0x0};
BOOL isOffice = false, isXPBrand = false;
unsigned flagVersion = 0;
public:
void setFlagVersion(unsigned int flagVersion);
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);
@ -91,22 +95,26 @@ 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) {
explicit Residue(ConfirmationID *in)
{
parent = in;
}
@ -121,25 +129,30 @@ public:
QWORD sqrt(QWORD what);
};
class Polynomial {
class Polynomial
{
ConfirmationID *parent;
public:
explicit Polynomial(ConfirmationID *in) {
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]);
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) {
explicit Divisor(ConfirmationID *in)
{
parent = in;
}
@ -149,5 +162,4 @@ public:
void mul128(const TDivisor *src, QWORD mult_lo, QWORD mult_hi, TDivisor *dst);
};
#endif // UMSKT_CONFID_H

View File

@ -67,7 +67,8 @@ int Divisor::find_divisor_v(TDivisor* d)
}
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,7 +101,8 @@ 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;
@ -200,19 +204,23 @@ void Divisor::add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst)
{
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'
@ -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;

View File

@ -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;
}

View File

@ -155,9 +155,14 @@ QWORD Residue::inverse(QWORD u, QWORD v)
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)
{

View File

@ -22,14 +22,13 @@
#include "libumskt.h"
#ifdef _WIN32
std::FILE *UMSKT::debug = std::fopen("NUL:", "w");
#else
std::FILE *UMSKT::debug = std::fopen("/dev/null", "w");
#endif
void UMSKT::setDebugOutput(std::FILE* input) {
void UMSKT::setDebugOutput(std::FILE *input)
{
debug = input;
}

View File

@ -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);
}

View File

@ -25,15 +25,15 @@
#include "../typedefs.h"
#include <string>
#include <iostream>
#include <sstream>
#include <string>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <fmt/core.h>
#include <fmt/format.h>
@ -59,7 +59,8 @@
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
#define BITMASK(n) ((1ULL << (n)) - 1)
class UMSKT {
class UMSKT
{
public:
static std::FILE *debug;
class PIDGEN2;
@ -69,5 +70,4 @@ public:
static void setDebugOutput(std::FILE *input);
};
#endif // UMSKT_LIBUMSKT_H

View File

@ -25,9 +25,12 @@
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;
}

View File

@ -25,7 +25,8 @@
#include "../libumskt.h"
EXPORT class PIDGEN2 {
EXPORT class PIDGEN2
{
public:
static bool isNumericString(char *input);
static bool isValidChannelID(char *channelID);

View File

@ -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,20 +61,13 @@ 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;
@ -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);

View File

@ -25,40 +25,17 @@
#include "PIDGEN3.h"
EXPORT class PIDGEN3::BINK1998 {
EXPORT class PIDGEN3::BINK1998
{
public:
static void Unpack(
QWORD (&pRaw)[2],
BOOL &pUpgrade,
DWORD &pSerial,
DWORD &pHash,
QWORD &pSignature
);
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

View File

@ -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,35 +55,22 @@ 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;
@ -108,9 +90,7 @@ 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]{},
BYTE msgDigest[SHA_DIGEST_LENGTH]{}, msgBuffer[SHA_MSG_LENGTH_2003]{}, xBin[FIELD_BYTES_2003]{},
yBin[FIELD_BYTES_2003]{};
// Assemble the first SHA message.
@ -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,9 +213,7 @@ 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]{},
BYTE msgDigest[SHA_DIGEST_LENGTH]{}, msgBuffer[SHA_MSG_LENGTH_2003]{}, xBin[FIELD_BYTES_2003]{},
yBin[FIELD_BYTES_2003]{};
// Convert resulting point coordinates to bytes.
@ -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);

View File

@ -25,43 +25,18 @@
#include "PIDGEN3.h"
EXPORT class PIDGEN3::BINK2002 {
EXPORT class PIDGEN3::BINK2002
{
public:
static void Unpack(
QWORD (&pRaw)[2],
BOOL &pUpgrade,
DWORD &pChannelID,
DWORD &pHash,
QWORD &pSignature,
DWORD &pAuthInfo
);
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

View File

@ -25,25 +25,20 @@
#include "../libumskt.h"
class PIDGEN3 {
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";

View File

@ -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);
}

View File

@ -22,14 +22,17 @@
#include "PIDGEN3.h"
int randomRange() {
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);

View File

@ -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,13 +37,15 @@ 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) {
switch (options.applicationMode)
{
case MODE_BINK1998_GENERATE:
return run.BINK1998Generate();

View File

@ -23,8 +23,8 @@
#ifndef UMSKT_TYPEDEFS_H
#define UMSKT_TYPEDEFS_H
#include <cstdint>
#include <cstdbool>
#include <cstdint>
#ifdef DEBUG
#include <cassert>

View File

@ -21,16 +21,16 @@
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "resource.h"
#include <windows.h>
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) {
switch (nReason)
{
case DLL_PROCESS_ATTACH:
// For optimization.
DisableThreadLibraryCalls(hDllHandle);