mirror of
https://github.com/xtexChooser/WindowsXPKg.git
synced 2024-08-23 10:12:34 +00:00
QWORD upgrade 1/3
This commit is contained in:
parent
d20cb1fa49
commit
632c84249c
3 changed files with 30 additions and 44 deletions
|
@ -46,7 +46,7 @@
|
||||||
#define NEXTSNBITS(field, n, offset) (((QWORD)field >> offset) & ((1ULL << (n)) - 1))
|
#define NEXTSNBITS(field, n, offset) (((QWORD)field >> offset) & ((1ULL << (n)) - 1))
|
||||||
#define FIRSTNBITS(field, n) NEXTSNBITS(field, n, 0)
|
#define FIRSTNBITS(field, n) NEXTSNBITS(field, n, 0)
|
||||||
|
|
||||||
#define BYDWORD(n) (n[0] | n[1] << 8 | n[2] << 16 | n[3] << 24)
|
#define BYDWORD(n) (*(n + 0) | *(n + 1) << 8 | *(n + 2) << 16 | *(n + 3) << 24)
|
||||||
#define BITMASK(n) ((1ULL << n) - 1)
|
#define BITMASK(n) ((1ULL << n) - 1)
|
||||||
|
|
||||||
// Confirmation ID generator constants
|
// Confirmation ID generator constants
|
||||||
|
|
|
@ -48,46 +48,40 @@ bool verifyServerKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey,
|
||||||
BN_CTX *context = BN_CTX_new();
|
BN_CTX *context = BN_CTX_new();
|
||||||
|
|
||||||
// Convert Base24 CD-key to bytecode.
|
// Convert Base24 CD-key to bytecode.
|
||||||
DWORD osFamily, hash, sig[2], prefix;
|
DWORD pChannelID, pHash, pSignature[2], pAuthInfo;
|
||||||
DWORD bKey[4]{};
|
DWORD bKey[4]{};
|
||||||
|
|
||||||
unbase24((BYTE *)bKey, cdKey);
|
unbase24((BYTE *)bKey, cdKey);
|
||||||
|
|
||||||
// Extract segments from the bytecode and reverse the signature.
|
// Extract segments from the bytecode and reverse the signature.
|
||||||
unpackServer(bKey, osFamily, hash, sig, prefix);
|
unpackServer(bKey, pChannelID, pHash, pSignature, pAuthInfo);
|
||||||
endian((BYTE *)sig, 8);
|
|
||||||
|
|
||||||
BYTE t[FIELD_BYTES_2003]{}, md[SHA_DIGEST_LENGTH]{};
|
BYTE msgDigest[SHA_DIGEST_LENGTH]{},
|
||||||
DWORD checkHash, newHash[2]{};
|
msgBuffer[SHA_MSG_LENGTH_2003]{},
|
||||||
|
xBin[FIELD_BYTES_2003]{},
|
||||||
|
yBin[FIELD_BYTES_2003]{};
|
||||||
|
|
||||||
// H = SHA-1(5D || OS Family || Hash || Prefix || 00 00)
|
// H = SHA-1(5D || OS Family || Hash || Prefix || 00 00)
|
||||||
t[0] = 0x5D;
|
msgBuffer[0x00] = 0x5D;
|
||||||
t[1] = (osFamily & 0xff);
|
msgBuffer[0x01] = (pChannelID & 0x00FF);
|
||||||
t[2] = (osFamily & 0xff00) >> 8;
|
msgBuffer[0x02] = (pChannelID & 0xFF00) >> 8;
|
||||||
t[3] = (hash & 0xff);
|
msgBuffer[0x03] = (pHash & 0x000000FF);
|
||||||
t[4] = (hash & 0xff00) >> 8;
|
msgBuffer[0x04] = (pHash & 0x0000FF00) >> 8;
|
||||||
t[5] = (hash & 0xff0000) >> 16;
|
msgBuffer[0x05] = (pHash & 0x00FF0000) >> 16;
|
||||||
t[6] = (hash & 0xff000000) >> 24;
|
msgBuffer[0x06] = (pHash & 0xFF000000) >> 24;
|
||||||
t[7] = (prefix & 0xff);
|
msgBuffer[0x07] = (pAuthInfo & 0x00FF);
|
||||||
t[8] = (prefix & 0xff00) >> 8;
|
msgBuffer[0x08] = (pAuthInfo & 0xFF00) >> 8;
|
||||||
t[9] = 0x00;
|
msgBuffer[0x09] = 0x00;
|
||||||
t[10] = 0x00;
|
msgBuffer[0x0A] = 0x00;
|
||||||
|
|
||||||
SHA1(t, 11, md);
|
SHA1(msgBuffer, 11, msgDigest);
|
||||||
|
|
||||||
// First word.
|
QWORD newHash = (BYDWORD(&msgDigest[4]) >> 2 & BITMASK(30)) << 32 | BYDWORD(msgDigest);
|
||||||
newHash[0] = md[0] | (md[1] << 8) | (md[2] << 16) | (md[3] << 24);
|
|
||||||
|
|
||||||
// Second word, right shift 2 bits.
|
|
||||||
newHash[1] = (md[4] | (md[5] << 8) | (md[6] << 16) | (md[7] << 24)) >> 2;
|
|
||||||
newHash[1] &= 0x3FFFFFFF;
|
|
||||||
|
|
||||||
endian((BYTE *)newHash, 8);
|
|
||||||
|
|
||||||
BIGNUM *x = BN_new();
|
BIGNUM *x = BN_new();
|
||||||
BIGNUM *y = BN_new();
|
BIGNUM *y = BN_new();
|
||||||
BIGNUM *s = BN_bin2bn((BYTE *)sig, 8, nullptr);
|
BIGNUM *s = BN_lebin2bn((BYTE *)pSignature, sizeof(pSignature), nullptr);
|
||||||
BIGNUM *e = BN_bin2bn((BYTE *)newHash, 8, nullptr);
|
BIGNUM *e = BN_lebin2bn((BYTE *)&newHash, sizeof(newHash), nullptr);
|
||||||
|
|
||||||
EC_POINT *u = EC_POINT_new(eCurve);
|
EC_POINT *u = EC_POINT_new(eCurve);
|
||||||
EC_POINT *v = EC_POINT_new(eCurve);
|
EC_POINT *v = EC_POINT_new(eCurve);
|
||||||
|
@ -111,19 +105,14 @@ bool verifyServerKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey,
|
||||||
// x = v.x; y = v.y;
|
// x = v.x; y = v.y;
|
||||||
EC_POINT_get_affine_coordinates(eCurve, v, x, y, context);
|
EC_POINT_get_affine_coordinates(eCurve, v, x, y, context);
|
||||||
|
|
||||||
BYTE msgDigest[SHA_DIGEST_LENGTH]{},
|
|
||||||
msgBuffer[SHA_MSG_LENGTH_2003]{},
|
|
||||||
xBin[FIELD_BYTES_2003]{},
|
|
||||||
yBin[FIELD_BYTES_2003]{};
|
|
||||||
|
|
||||||
// Convert resulting point coordinates to bytes.
|
// Convert resulting point coordinates to bytes.
|
||||||
BN_bn2lebin(x, xBin, FIELD_BYTES_2003);
|
BN_bn2lebin(x, xBin, FIELD_BYTES_2003);
|
||||||
BN_bn2lebin(y, yBin, FIELD_BYTES_2003);
|
BN_bn2lebin(y, yBin, FIELD_BYTES_2003);
|
||||||
|
|
||||||
// Assemble the SHA message.
|
// Assemble the SHA message.
|
||||||
msgBuffer[0] = 0x79;
|
msgBuffer[0x00] = 0x79;
|
||||||
msgBuffer[1] = (osFamily & 0xff);
|
msgBuffer[0x01] = (pChannelID & 0x00FF);
|
||||||
msgBuffer[2] = (osFamily & 0xff00) >> 8;
|
msgBuffer[0x02] = (pChannelID & 0xFF00) >> 8;
|
||||||
|
|
||||||
memcpy((void *)&msgBuffer[3], (void *)xBin, FIELD_BYTES_2003);
|
memcpy((void *)&msgBuffer[3], (void *)xBin, FIELD_BYTES_2003);
|
||||||
memcpy((void *)&msgBuffer[3 + FIELD_BYTES_2003], (void *)yBin, FIELD_BYTES_2003);
|
memcpy((void *)&msgBuffer[3 + FIELD_BYTES_2003], (void *)yBin, FIELD_BYTES_2003);
|
||||||
|
@ -131,8 +120,8 @@ bool verifyServerKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey,
|
||||||
// Retrieve the message digest.
|
// Retrieve the message digest.
|
||||||
SHA1(msgBuffer, SHA_MSG_LENGTH_2003, msgDigest);
|
SHA1(msgBuffer, SHA_MSG_LENGTH_2003, msgDigest);
|
||||||
|
|
||||||
// Translate the byte digest into a 32-bit integer - this is our computed hash.
|
// Translate the byte digest into a 32-bit integer - this is our computed pHash.
|
||||||
// Truncate the hash to 28 bits.
|
// Truncate the pHash to 28 bits.
|
||||||
// Hash = First31(SHA-1(79 || OS Family || v.x || v.y))
|
// Hash = First31(SHA-1(79 || OS Family || v.x || v.y))
|
||||||
DWORD compHash = BYDWORD(msgDigest) & BITMASK(31);
|
DWORD compHash = BYDWORD(msgDigest) & BITMASK(31);
|
||||||
|
|
||||||
|
@ -146,8 +135,8 @@ bool verifyServerKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey,
|
||||||
EC_POINT_free(v);
|
EC_POINT_free(v);
|
||||||
EC_POINT_free(u);
|
EC_POINT_free(u);
|
||||||
|
|
||||||
// If we managed to generate a key with the same hash, the key is correct.
|
// If we managed to generate a key with the same pHash, the key is correct.
|
||||||
return compHash == hash;
|
return compHash == pHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateServerKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, DWORD *osFamily, DWORD *prefix) {
|
void generateServerKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, DWORD *osFamily, DWORD *prefix) {
|
||||||
|
|
|
@ -102,8 +102,6 @@ bool verifyXPKey(
|
||||||
xBin[FIELD_BYTES]{},
|
xBin[FIELD_BYTES]{},
|
||||||
yBin[FIELD_BYTES]{};
|
yBin[FIELD_BYTES]{};
|
||||||
|
|
||||||
DWORD compHash;
|
|
||||||
|
|
||||||
// Convert resulting point coordinates to bytes.
|
// Convert resulting point coordinates to bytes.
|
||||||
BN_bn2lebin(x, xBin, FIELD_BYTES);
|
BN_bn2lebin(x, xBin, FIELD_BYTES);
|
||||||
BN_bn2lebin(y, yBin, FIELD_BYTES);
|
BN_bn2lebin(y, yBin, FIELD_BYTES);
|
||||||
|
@ -118,8 +116,7 @@ bool verifyXPKey(
|
||||||
|
|
||||||
// Translate the byte digest into a 32-bit integer - this is our computed hash.
|
// Translate the byte digest into a 32-bit integer - this is our computed hash.
|
||||||
// Truncate the hash to 28 bits.
|
// Truncate the hash to 28 bits.
|
||||||
compHash = BYDWORD(msgDigest) >> 4;
|
DWORD compHash = BYDWORD(msgDigest) >> 4 & BITMASK(28);
|
||||||
compHash &= BITMASK(28);
|
|
||||||
|
|
||||||
BN_free(e);
|
BN_free(e);
|
||||||
BN_free(s);
|
BN_free(s);
|
||||||
|
|
Loading…
Reference in a new issue