Simplify pointer arithmetics

This commit is contained in:
Andrew 2023-06-04 14:54:22 +03:00
parent 8e4285c960
commit 08ec7cb9bb
4 changed files with 33 additions and 37 deletions

View File

@ -67,8 +67,8 @@ EC_GROUP *initializeEllipticCurve(
std::string generatorYSel, std::string generatorYSel,
std::string publicKeyXSel, std::string publicKeyXSel,
std::string publicKeyYSel, std::string publicKeyYSel,
EC_POINT **genPoint, EC_POINT *&genPoint,
EC_POINT **pubPoint EC_POINT *&pubPoint
); );
// key.cpp // key.cpp
@ -92,8 +92,8 @@ Options parseCommandLine(int argc, char* argv[]);
void showHelp(char *argv[]); void showHelp(char *argv[]);
// xp.cpp // xp.cpp
bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, char *cdKey); bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, char (&cdKey)[25]);
void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, DWORD *pRaw); void generateXPKey(EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, DWORD pRaw, char (&cdKey)[25]);
// server.cpp // server.cpp

View File

@ -99,8 +99,8 @@ int main(int argc, char *argv[]) {
keys["BINK"][BINKID]["g"]["y"].get<std::string>(), keys["BINK"][BINKID]["g"]["y"].get<std::string>(),
keys["BINK"][BINKID]["pub"]["x"].get<std::string>(), keys["BINK"][BINKID]["pub"]["x"].get<std::string>(),
keys["BINK"][BINKID]["pub"]["y"].get<std::string>(), keys["BINK"][BINKID]["pub"]["y"].get<std::string>(),
&genPoint, genPoint,
&pubPoint pubPoint
); );
// Calculation // Calculation
@ -125,7 +125,7 @@ int main(int argc, char *argv[]) {
BN_sub(privateKey, genOrder, privateKey); BN_sub(privateKey, genOrder, privateKey);
nRaw <<= 1; nRaw <<= 1;
generateXPKey(pKey, eCurve, genPoint, genOrder, privateKey, &nRaw); generateXPKey(eCurve, genPoint, genOrder, privateKey, nRaw, pKey);
print_product_key(pKey); print_product_key(pKey);
std::cout << std::endl << std::endl; std::cout << std::endl << std::endl;

View File

@ -27,8 +27,8 @@ EC_GROUP *initializeEllipticCurve(
const std::string generatorYSel, const std::string generatorYSel,
const std::string publicKeyXSel, const std::string publicKeyXSel,
const std::string publicKeyYSel, const std::string publicKeyYSel,
EC_POINT **genPoint, EC_POINT *&genPoint,
EC_POINT **pubPoint EC_POINT *&pubPoint
) { ) {
// Initialize BIGNUM and BIGNUMCTX structures. // Initialize BIGNUM and BIGNUMCTX structures.
// BIGNUM - Large numbers // BIGNUM - Large numbers
@ -69,16 +69,16 @@ EC_GROUP *initializeEllipticCurve(
EC_GROUP *eCurve = EC_GROUP_new_curve_GFp(p, a, b, context); 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). // Create new point for the generator on the elliptic curve and set its coordinates to (genX; genY).
*genPoint = EC_POINT_new(eCurve); genPoint = EC_POINT_new(eCurve);
EC_POINT_set_affine_coordinates(eCurve, *genPoint, generatorX, generatorY, context); EC_POINT_set_affine_coordinates(eCurve, genPoint, generatorX, generatorY, context);
// Create new point for the public key on the elliptic curve and set its coordinates to (pubX; pubY). // Create new point for the public key on the elliptic curve and set its coordinates to (pubX; pubY).
*pubPoint = EC_POINT_new(eCurve); pubPoint = EC_POINT_new(eCurve);
EC_POINT_set_affine_coordinates(eCurve, *pubPoint, publicKeyX, publicKeyY, context); 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) == 1); assert(EC_POINT_is_on_curve(eCurve, genPoint, context) == true);
assert(EC_POINT_is_on_curve(eCurve, *pubPoint, context) == 1); assert(EC_POINT_is_on_curve(eCurve, pubPoint, context) == true);
// Cleanup // Cleanup
BN_CTX_free(context); BN_CTX_free(context);

View File

@ -18,28 +18,24 @@
#include "header.h" #include "header.h"
/* Unpacks the Windows XP Product Key. */ /* Unpacks the Windows XP Product Key. */
void unpackXP(DWORD *pRaw, DWORD *pSerial, DWORD *pHash, DWORD *pSignature) { void unpackXP(DWORD (&pRaw)[4], DWORD &pSerial, DWORD &pHash, DWORD (&pSignature)[2]) {
// We're assuming that the quantity of information within the product key is at most 114 bits. // We're assuming that the quantity of information within the product key is at most 114 bits.
// log2(24^25) = 114. // log2(24^25) = 114.
// Serial = Bits [0..30] -> 31 bits // Serial = Bits [0..30] -> 31 bits
if (pSerial) pSerial = pRaw[0] & 0x7fffffff;
pSerial[0] = pRaw[0] & 0x7fffffff;
// Hash (e) = Bits [31..58] -> 28 bits // Hash (e) = Bits [31..58] -> 28 bits
if (pHash) pHash = ((pRaw[0] >> 31) | (pRaw[1] << 1)) & 0xfffffff;
pHash[0] = ((pRaw[0] >> 31) | (pRaw[1] << 1)) & 0xfffffff;
// Signature (s) = Bits [59..113] -> 55 bits // Signature (s) = Bits [59..113] -> 55 bits
if (pSignature) {
pSignature[0] = (pRaw[1] >> 27) | (pRaw[2] << 5); pSignature[0] = (pRaw[1] >> 27) | (pRaw[2] << 5);
pSignature[1] = (pRaw[2] >> 27) | (pRaw[3] << 5); pSignature[1] = (pRaw[2] >> 27) | (pRaw[3] << 5);
}
} }
/* Packs the Windows XP Product Key. */ /* Packs the Windows XP Product Key. */
void packXP(DWORD *pRaw, const DWORD pSerial, const DWORD pHash, const DWORD *pSignature) { void packXP(DWORD (&pRaw)[4], DWORD pSerial, DWORD pHash, DWORD (&pSignature)[2]) {
pRaw[0] = pSerial | ((pHash & 1) << 31); pRaw[0] = pSerial | ((pHash & 1) << 31);
pRaw[1] = (pHash >> 1) | ((pSignature[0] & 0x1f) << 27); pRaw[1] = (pHash >> 1) | ((pSignature[0] & 0x1f) << 27);
pRaw[2] = (pSignature[0] >> 5) | (pSignature[1] << 27); pRaw[2] = (pSignature[0] >> 5) | (pSignature[1] << 27);
@ -47,7 +43,7 @@ void packXP(DWORD *pRaw, const DWORD pSerial, const DWORD pHash, const DWORD *pS
} }
/* Verify Product Key */ /* Verify Product Key */
bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, char *cdKey) { bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, char (&cdKey)[25]) {
BN_CTX *context = BN_CTX_new(); BN_CTX *context = BN_CTX_new();
// Convert Base24 CD-key to bytecode. // Convert Base24 CD-key to bytecode.
@ -57,7 +53,7 @@ bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, cha
unbase24(bKey, cdKey); unbase24(bKey, cdKey);
// Extract data, hash and signature from the bytecode. // Extract data, hash and signature from the bytecode.
unpackXP(bKey, &pID, &checkHash, sig); unpackXP(bKey, pID, checkHash, sig);
// e = Hash // e = Hash
// s = Signature // s = Signature
@ -150,7 +146,7 @@ bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, cha
} }
/* Generate a valid Product Key. */ /* Generate a valid Product Key. */
void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, DWORD *pRaw) { void generateXPKey(EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, DWORD pRaw, char (&pKey)[25]) {
EC_POINT *r = EC_POINT_new(eCurve); EC_POINT *r = EC_POINT_new(eCurve);
BN_CTX *ctx = BN_CTX_new(); BN_CTX *ctx = BN_CTX_new();
@ -182,10 +178,10 @@ void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *or
SHA1_Init(&hContext); SHA1_Init(&hContext);
// Chop Raw Product Key into 4 bytes. // Chop Raw Product Key into 4 bytes.
t[0] = (*pRaw & 0xff); t[0] = (pRaw & 0xff);
t[1] = (*pRaw & 0xff00) >> 8; t[1] = (pRaw & 0xff00) >> 8;
t[2] = (*pRaw & 0xff0000) >> 16; t[2] = (pRaw & 0xff0000) >> 16;
t[3] = (*pRaw & 0xff000000) >> 24; t[3] = (pRaw & 0xff000000) >> 24;
// Hash chunk of data. // Hash chunk of data.
SHA1_Update(&hContext, t, sizeof(t)); SHA1_Update(&hContext, t, sizeof(t));
@ -229,13 +225,13 @@ void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *or
endian((BYTE *)sig, BN_num_bytes(s)); endian((BYTE *)sig, BN_num_bytes(s));
// Pack product key. // Pack product key.
packXP(bKey, *pRaw, hash, sig); packXP(bKey, pRaw, hash, sig);
//printf("PID: %.8X\nHash: %.8X\nSig: %.8X %.8X\n", pRaw[0], hash, sig[1], sig[0]); //printf("PID: %.8X\nHash: %.8X\nSig: %.8X %.8X\n", pRaw[0], hash, sig[1], sig[0]);
std::cout << " PID: " << std::hex << std::setw(8) << std::setfill('0') << pRaw[0] << std::endl std::cout << " PID: " << std::hex << std::setw(8) << std::setfill('0') << pRaw << std::endl
<< "Hash: " << std::hex << std::setw(8) << std::setfill('0') << hash << std::endl << "Hash: " << std::hex << std::setw(8) << std::setfill('0') << hash << std::endl
<< " Sig: " << std::hex << std::setw(8) << std::setfill('0') << sig[1] << " " << " Sig: " << std::hex << std::setw(8) << std::setfill('0') << sig[0] << " "
<< std::hex << std::setw(8) << std::setfill('0') << sig[2] << std::endl << std::hex << std::setw(8) << std::setfill('0') << sig[1] << std::endl
<< std::endl; << std::endl;
} while (bKey[3] >= 0x40000); } while (bKey[3] >= 0x40000);