This commit is contained in:
Alex Page 2023-06-23 20:29:13 -04:00
parent 7bd191e6be
commit b73401cefb
4 changed files with 42 additions and 41 deletions

View file

@ -92,10 +92,11 @@ impl ProductKey {
let mut c = BigNum::new()?; let mut c = BigNum::new()?;
let mut s = BigNum::new()?; let mut s = BigNum::new()?;
let mut s_2 = BigNum::new()?;
let mut x = BigNum::new()?; let mut x = BigNum::new()?;
let mut y = BigNum::new()?; let mut y = BigNum::new()?;
let mut ek: BigNum;
let p_data = p_serial << 1 | p_upgrade as u32; let p_data = p_serial << 1 | p_upgrade as u32;
let product_key = loop { let product_key = loop {
@ -128,10 +129,10 @@ impl ProductKey {
let p_hash: u32 = let p_hash: u32 =
u32::from_le_bytes(msg_digest[0..4].try_into().unwrap()) >> 4 & bitmask(28) as u32; u32::from_le_bytes(msg_digest[0..4].try_into().unwrap()) >> 4 & bitmask(28) as u32;
s_2.copy_from_slice(&private_key.to_vec())?; ek = (*private_key).to_owned()?;
s_2.mul_word(p_hash)?; ek.mul_word(p_hash)?;
s.mod_add(&s_2, &c, gen_order, &mut num_context)?; s.mod_add(&ek, &c, gen_order, &mut num_context)?;
let p_signature = u64::from_be_bytes(s.to_vec_padded(8)?.try_into().unwrap()); let p_signature = u64::from_be_bytes(s.to_vec_padded(8)?.try_into().unwrap());
@ -154,9 +155,7 @@ impl ProductKey {
base_point: &EcPoint, base_point: &EcPoint,
public_key: &EcPoint, public_key: &EcPoint,
) -> Result<bool> { ) -> Result<bool> {
let mut num_context = BigNumContext::new()?; let mut ctx = BigNumContext::new()?;
let p_data = self.serial << 1 | self.upgrade as u32;
let e = BigNum::from_u32(self.hash)?; let e = BigNum::from_u32(self.hash)?;
let s = BigNum::from_slice(&self.signature.to_be_bytes())?; let s = BigNum::from_slice(&self.signature.to_be_bytes())?;
@ -165,15 +164,16 @@ impl ProductKey {
let mut t = EcPoint::new(e_curve)?; let mut t = EcPoint::new(e_curve)?;
let mut p = EcPoint::new(e_curve)?; let mut p = EcPoint::new(e_curve)?;
let mut p_2 = EcPoint::new(e_curve)?;
t.mul(e_curve, base_point, &s, &num_context)?; t.mul(e_curve, base_point, &s, &ctx)?;
p.mul(e_curve, public_key, &e, &num_context)?; p.mul(e_curve, public_key, &e, &ctx)?;
p_2.mul(e_curve, public_key, &e, &num_context)?;
p.add(e_curve, &t, &p_2, &mut num_context)?; {
let p_copy = p.to_owned(e_curve)?;
p.add(e_curve, &t, &p_copy, &mut ctx)?;
}
p.affine_coordinates(e_curve, &mut x, &mut y, &mut num_context)?; p.affine_coordinates(e_curve, &mut x, &mut y, &mut ctx)?;
let mut msg_buffer: [u8; SHA_MSG_LENGTH] = [0; SHA_MSG_LENGTH]; let mut msg_buffer: [u8; SHA_MSG_LENGTH] = [0; SHA_MSG_LENGTH];
@ -182,6 +182,8 @@ impl ProductKey {
let mut y_bin = y.to_vec_padded(FIELD_BYTES as i32)?; let mut y_bin = y.to_vec_padded(FIELD_BYTES as i32)?;
y_bin.reverse(); y_bin.reverse();
let p_data = self.serial << 1 | self.upgrade as u32;
msg_buffer[0..4].copy_from_slice(&p_data.to_le_bytes()); msg_buffer[0..4].copy_from_slice(&p_data.to_le_bytes());
msg_buffer[4..4 + FIELD_BYTES].copy_from_slice(&x_bin); msg_buffer[4..4 + FIELD_BYTES].copy_from_slice(&x_bin);
msg_buffer[4 + FIELD_BYTES..4 + FIELD_BYTES * 2].copy_from_slice(&y_bin); msg_buffer[4 + FIELD_BYTES..4 + FIELD_BYTES * 2].copy_from_slice(&y_bin);
@ -194,21 +196,21 @@ impl ProductKey {
Ok(hash == self.hash) Ok(hash == self.hash)
} }
fn from_packed(p_raw: &[u8]) -> Result<Self> { fn from_packed(packed_key: &[u8]) -> Result<Self> {
let mut reader = BitReader::new(p_raw); let mut reader = BitReader::new(packed_key);
// The signature length is unknown, but everything else is, so we can calculate it // The signature length isn't known, but everything else is, so we can calculate it
let signature_length_bits = (p_raw.len() * 8) as u8 - EVERYTHING_ELSE; let signature_length_bits = (packed_key.len() * 8) as u8 - EVERYTHING_ELSE;
let p_signature = reader.read_u64(signature_length_bits)?; let signature = reader.read_u64(signature_length_bits)?;
let p_hash = reader.read_u32(HASH_LENGTH_BITS)?; let hash = reader.read_u32(HASH_LENGTH_BITS)?;
let p_serial = reader.read_u32(SERIAL_LENGTH_BITS)?; let serial = reader.read_u32(SERIAL_LENGTH_BITS)?;
let p_upgrade = reader.read_bool()?; let upgrade = reader.read_bool()?;
Ok(Self { Ok(Self {
upgrade: p_upgrade, upgrade,
serial: p_serial, serial,
hash: p_hash, hash,
signature: p_signature, signature,
}) })
} }

View file

@ -279,22 +279,23 @@ impl ProductKey {
Ok(hash == self.hash) Ok(hash == self.hash)
} }
fn from_packed(p_raw: &[u8]) -> Result<Self> { fn from_packed(packed_key: &[u8]) -> Result<Self> {
let mut reader = BitReader::new(p_raw); let mut reader = BitReader::new(packed_key);
let auth_info_length_bits = (p_raw.len() * 8) as u8 - EVERYTHING_ELSE; // The auth info length isn't known, but everything else is, so we can calculate it
let auth_info_length_bits = (packed_key.len() * 8) as u8 - EVERYTHING_ELSE;
let p_auth_info = reader.read_u32(auth_info_length_bits)?; let auth_info = reader.read_u32(auth_info_length_bits)?;
let p_signature = reader.read_u64(SIGNATURE_LENGTH_BITS)?; let signature = reader.read_u64(SIGNATURE_LENGTH_BITS)?;
let p_hash = reader.read_u32(HASH_LENGTH_BITS)?; let hash = reader.read_u32(HASH_LENGTH_BITS)?;
let p_channel_id = reader.read_u32(CHANNEL_ID_LENGTH_BITS)?; let channel_id = reader.read_u32(CHANNEL_ID_LENGTH_BITS)?;
let p_upgrade = reader.read_bool()?; let upgrade = reader.read_bool()?;
Ok(Self { Ok(Self {
upgrade: p_upgrade, upgrade,
channel_id: p_channel_id, channel_id,
hash: p_hash, hash,
signature: p_signature, signature,
auth_info: p_auth_info, auth_info,
}) })
} }

View file

@ -3,7 +3,7 @@ use std::collections::VecDeque;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use openssl::bn::BigNum; use openssl::bn::BigNum;
use crate::PK_LENGTH; const PK_LENGTH: usize = 25;
/// The allowed character set in a product key. /// The allowed character set in a product key.
pub const P_KEY_CHARSET: [char; 24] = [ pub const P_KEY_CHARSET: [char; 24] = [

View file

@ -4,5 +4,3 @@ pub mod confid;
pub mod crypto; pub mod crypto;
mod key; mod key;
mod math; mod math;
const PK_LENGTH: usize = 25;