mirror of
https://github.com/freemkv/freemkv-unlock.git
synced 2026-10-07 18:13:11 +00:00
Move to rand 0.10 and aes 0.9
Both are API renames rather than behaviour changes, but this is the AACS and CSS crypto path, so it is verified by output rather than by the fact that it compiles. rand: `RngCore` no longer sits at the crate root -- `fill_bytes` moved to the re-exported `Rng` trait -- and `thread_rng()` is now `rng()`. aes: the cipher traits gained their `BlockCipher` prefix and `generic_array::GenericArray` became `Array`. The obvious translation uses `Array::from_slice`, which is deprecated in the new version and would fail clippy's `-D warnings`; these use the `From<[T; N]>` conversion the crate points at instead. The proof this is byte-exact is `test_aes_cmac_nist_kat_full_block`, which checks the exact MAC from NIST SP 800-38B Appendix D.1 -- a wrong byte order or a mis-sized array cannot produce that value. All 95 tests pass in both debug and release.
This commit is contained in:
+2
-2
@@ -24,5 +24,5 @@ num-bigint = "0.5"
|
|||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
sha1 = "0.10"
|
sha1 = "0.10"
|
||||||
sha2 = "0.11"
|
sha2 = "0.11"
|
||||||
aes = "0.8"
|
aes = "0.9"
|
||||||
rand = "0.8"
|
rand = "0.10"
|
||||||
|
|||||||
+21
-21
@@ -391,8 +391,8 @@ fn ecdsa_sign(priv_key: &[u8; 20], data: &[u8]) -> ([u8; 20], [u8; 20]) {
|
|||||||
// two); a biased ECDSA nonce is a known key-recovery weakness, so
|
// two); a biased ECDSA nonce is a known key-recovery weakness, so
|
||||||
// we reject and redraw any candidate >= n instead.
|
// we reject and redraw any candidate >= n instead.
|
||||||
let mut k_bytes = [0u8; 20];
|
let mut k_bytes = [0u8; 20];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut k_bytes);
|
rand::rng().fill_bytes(&mut k_bytes);
|
||||||
let k = BigUint::from_bytes_be(&k_bytes);
|
let k = BigUint::from_bytes_be(&k_bytes);
|
||||||
if k.is_zero() || k >= n {
|
if k.is_zero() || k >= n {
|
||||||
continue;
|
continue;
|
||||||
@@ -490,8 +490,8 @@ fn ecdsa_sign_p256(priv_key: &[u8; 32], data: &[u8]) -> ([u8; 32], [u8; 32]) {
|
|||||||
// (avoid the modulo bias that reducing raw RNG bytes mod n would
|
// (avoid the modulo bias that reducing raw RNG bytes mod n would
|
||||||
// introduce).
|
// introduce).
|
||||||
let mut k_bytes = [0u8; 32];
|
let mut k_bytes = [0u8; 32];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut k_bytes);
|
rand::rng().fill_bytes(&mut k_bytes);
|
||||||
let k = BigUint::from_bytes_be(&k_bytes);
|
let k = BigUint::from_bytes_be(&k_bytes);
|
||||||
if k.is_zero() || k >= n {
|
if k.is_zero() || k >= n {
|
||||||
continue;
|
continue;
|
||||||
@@ -703,8 +703,8 @@ fn generate_host_key_pair_p256() -> ([u8; 32], [u8; 32], [u8; 32]) {
|
|||||||
|
|
||||||
let (d, q) = loop {
|
let (d, q) = loop {
|
||||||
let mut priv_bytes = [0u8; 32];
|
let mut priv_bytes = [0u8; 32];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut priv_bytes);
|
rand::rng().fill_bytes(&mut priv_bytes);
|
||||||
// d == 0 (prob ~1/n) would yield the point at infinity / an
|
// d == 0 (prob ~1/n) would yield the point at infinity / an
|
||||||
// all-zero key and degenerate the bus key — reject and retry,
|
// all-zero key and degenerate the bus key — reject and retry,
|
||||||
// matching the AACS 1.0 sibling generate_host_key_pair.
|
// matching the AACS 1.0 sibling generate_host_key_pair.
|
||||||
@@ -735,8 +735,8 @@ fn generate_host_key_pair() -> ([u8; 20], [u8; 20], [u8; 20]) {
|
|||||||
|
|
||||||
let (d, q) = loop {
|
let (d, q) = loop {
|
||||||
let mut priv_bytes = [0u8; 20];
|
let mut priv_bytes = [0u8; 20];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut priv_bytes);
|
rand::rng().fill_bytes(&mut priv_bytes);
|
||||||
let d = BigUint::from_bytes_be(&priv_bytes) % &n;
|
let d = BigUint::from_bytes_be(&priv_bytes) % &n;
|
||||||
if d.is_zero() {
|
if d.is_zero() {
|
||||||
continue;
|
continue;
|
||||||
@@ -771,13 +771,13 @@ fn generate_host_key_pair() -> ([u8; 20], [u8; 20], [u8; 20]) {
|
|||||||
/// padding.
|
/// padding.
|
||||||
fn aes_cmac_16(data: &[u8; 16], key: &[u8; 16]) -> [u8; 16] {
|
fn aes_cmac_16(data: &[u8; 16], key: &[u8; 16]) -> [u8; 16] {
|
||||||
use aes::Aes128;
|
use aes::Aes128;
|
||||||
use aes::cipher::{BlockEncrypt, KeyInit, generic_array::GenericArray};
|
use aes::cipher::{Array, BlockCipherEncrypt, KeyInit};
|
||||||
|
|
||||||
let cipher = Aes128::new(GenericArray::from_slice(key));
|
let cipher = Aes128::new(&(*key).into());
|
||||||
|
|
||||||
// For single-block CMAC:
|
// For single-block CMAC:
|
||||||
// 1. Generate subkey K1
|
// 1. Generate subkey K1
|
||||||
let mut l = GenericArray::clone_from_slice(&[0u8; 16]);
|
let mut l: Array<u8, _> = [0u8; 16].into();
|
||||||
cipher.encrypt_block(&mut l);
|
cipher.encrypt_block(&mut l);
|
||||||
|
|
||||||
let mut k1 = [0u8; 16];
|
let mut k1 = [0u8; 16];
|
||||||
@@ -795,7 +795,7 @@ fn aes_cmac_16(data: &[u8; 16], key: &[u8; 16]) -> [u8; 16] {
|
|||||||
for i in 0..16 {
|
for i in 0..16 {
|
||||||
block[i] = data[i] ^ k1[i];
|
block[i] = data[i] ^ k1[i];
|
||||||
}
|
}
|
||||||
let mut ga = GenericArray::clone_from_slice(&block);
|
let mut ga: Array<u8, _> = block.into();
|
||||||
cipher.encrypt_block(&mut ga);
|
cipher.encrypt_block(&mut ga);
|
||||||
|
|
||||||
let mut mac = [0u8; 16];
|
let mut mac = [0u8; 16];
|
||||||
@@ -903,8 +903,8 @@ pub fn aacs_authenticate(
|
|||||||
|
|
||||||
// Step 3: Generate host nonce and ephemeral key pair
|
// Step 3: Generate host nonce and ephemeral key pair
|
||||||
let mut host_nonce = [0u8; 20];
|
let mut host_nonce = [0u8; 20];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut host_nonce);
|
rand::rng().fill_bytes(&mut host_nonce);
|
||||||
let (host_key, host_key_point_x, host_key_point_y) = generate_host_key_pair();
|
let (host_key, host_key_point_x, host_key_point_y) = generate_host_key_pair();
|
||||||
|
|
||||||
// Step 4: Send host certificate + nonce (SEND KEY format 0x01)
|
// Step 4: Send host certificate + nonce (SEND KEY format 0x01)
|
||||||
@@ -1066,8 +1066,8 @@ fn aacs2_authenticate_p256(
|
|||||||
|
|
||||||
// Step 3: Generate host nonce + P-256 ephemeral key pair
|
// Step 3: Generate host nonce + P-256 ephemeral key pair
|
||||||
let mut host_nonce = [0u8; 20];
|
let mut host_nonce = [0u8; 20];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut host_nonce);
|
rand::rng().fill_bytes(&mut host_nonce);
|
||||||
let (host_eph_key, host_eph_pub_x, host_eph_pub_y) = generate_host_key_pair_p256();
|
let (host_eph_key, host_eph_pub_x, host_eph_pub_y) = generate_host_key_pair_p256();
|
||||||
|
|
||||||
// Step 4: Send AACS 2.0 host certificate + nonce
|
// Step 4: Send AACS 2.0 host certificate + nonce
|
||||||
@@ -1490,8 +1490,8 @@ mod tests {
|
|||||||
|
|
||||||
// Generate random P-256 key pair
|
// Generate random P-256 key pair
|
||||||
let mut priv_bytes = [0u8; 32];
|
let mut priv_bytes = [0u8; 32];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut priv_bytes);
|
rand::rng().fill_bytes(&mut priv_bytes);
|
||||||
let d = BigUint::from_bytes_be(&priv_bytes) % &n;
|
let d = BigUint::from_bytes_be(&priv_bytes) % &n;
|
||||||
let priv_key: [u8; 32] = to_bytes_be_padded(&d, 32).try_into().unwrap();
|
let priv_key: [u8; 32] = to_bytes_be_padded(&d, 32).try_into().unwrap();
|
||||||
|
|
||||||
@@ -1514,9 +1514,9 @@ mod tests {
|
|||||||
|
|
||||||
let mut pa = [0u8; 32];
|
let mut pa = [0u8; 32];
|
||||||
let mut pb = [0u8; 32];
|
let mut pb = [0u8; 32];
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut pa);
|
rand::rng().fill_bytes(&mut pa);
|
||||||
rand::thread_rng().fill_bytes(&mut pb);
|
rand::rng().fill_bytes(&mut pb);
|
||||||
let da = BigUint::from_bytes_be(&pa) % &n;
|
let da = BigUint::from_bytes_be(&pa) % &n;
|
||||||
let db = BigUint::from_bytes_be(&pb) % &n;
|
let db = BigUint::from_bytes_be(&pb) % &n;
|
||||||
let priv_a: [u8; 32] = to_bytes_be_padded(&da, 32).try_into().unwrap();
|
let priv_a: [u8; 32] = to_bytes_be_padded(&da, 32).try_into().unwrap();
|
||||||
|
|||||||
+3
-3
@@ -9,7 +9,7 @@ mod error;
|
|||||||
mod handshake;
|
mod handshake;
|
||||||
|
|
||||||
use aes::Aes128;
|
use aes::Aes128;
|
||||||
use aes::cipher::{BlockDecrypt, KeyInit, generic_array::GenericArray};
|
use aes::cipher::{Array, BlockCipherDecrypt, KeyInit};
|
||||||
|
|
||||||
use crate::scsi::ScsiTransport;
|
use crate::scsi::ScsiTransport;
|
||||||
use crate::{DiscKind, UnlockCtx, UnlockError, Unlocked, Unlocker};
|
use crate::{DiscKind, UnlockCtx, UnlockError, Unlocked, Unlocker};
|
||||||
@@ -17,8 +17,8 @@ use crate::{DiscKind, UnlockCtx, UnlockError, Unlocked, Unlocker};
|
|||||||
/// AES-128-ECB decrypt a single 16-byte block — used to decrypt the bus key /
|
/// AES-128-ECB decrypt a single 16-byte block — used to decrypt the bus key /
|
||||||
/// read_data_key the drive returns after the handshake.
|
/// read_data_key the drive returns after the handshake.
|
||||||
pub(crate) fn aes_ecb_decrypt(key: &[u8; 16], data: &[u8; 16]) -> [u8; 16] {
|
pub(crate) fn aes_ecb_decrypt(key: &[u8; 16], data: &[u8; 16]) -> [u8; 16] {
|
||||||
let cipher = Aes128::new(GenericArray::from_slice(key));
|
let cipher = Aes128::new(&(*key).into());
|
||||||
let mut block = GenericArray::clone_from_slice(data);
|
let mut block: Array<u8, _> = (*data).into();
|
||||||
cipher.decrypt_block(&mut block);
|
cipher.decrypt_block(&mut block);
|
||||||
let mut out = [0u8; 16];
|
let mut out = [0u8; 16];
|
||||||
out.copy_from_slice(&block);
|
out.copy_from_slice(&block);
|
||||||
|
|||||||
+2
-2
@@ -299,8 +299,8 @@ fn establish_authenticated_session(scsi: &mut dyn ScsiTransport) -> Result<u8> {
|
|||||||
// handshake.
|
// handshake.
|
||||||
let mut host_challenge = [0u8; 10];
|
let mut host_challenge = [0u8; 10];
|
||||||
{
|
{
|
||||||
use rand::RngCore;
|
use rand::Rng;
|
||||||
rand::thread_rng().fill_bytes(&mut host_challenge);
|
rand::rng().fill_bytes(&mut host_challenge);
|
||||||
}
|
}
|
||||||
let mut hc_buf = [0u8; 16];
|
let mut hc_buf = [0u8; 16];
|
||||||
hc_buf[0] = 0x00;
|
hc_buf[0] = 0x00;
|
||||||
|
|||||||
Reference in New Issue
Block a user