chore(i18n): finish translating code comments and scripts to English
CI / Format and clippy (push) Successful in 1m57s
CI / Dependency audit (push) Successful in 13s
CI / Check desktop app (Linux) (push) Successful in 3m54s
CI / Tests (Linux) (push) Failing after 7m25s
Release / Create release (push) Successful in 6s
Release / CLI (linux-aarch64) (push) Successful in 1m48s
Release / CLI (linux-x86_64) (push) Successful in 2m39s
Release / Desktop app (linux-aarch64) (push) Successful in 10m9s
Release / Desktop app (linux-x86_64) (push) Successful in 12m20s
Release / Desktop app (windows) (push) Successful in 7m32s
Release / Build latest.json (push) Successful in 5s
CI / Format and clippy (push) Successful in 1m57s
CI / Dependency audit (push) Successful in 13s
CI / Check desktop app (Linux) (push) Successful in 3m54s
CI / Tests (Linux) (push) Failing after 7m25s
Release / Create release (push) Successful in 6s
Release / CLI (linux-aarch64) (push) Successful in 1m48s
Release / CLI (linux-x86_64) (push) Successful in 2m39s
Release / Desktop app (linux-aarch64) (push) Successful in 10m9s
Release / Desktop app (linux-x86_64) (push) Successful in 12m20s
Release / Desktop app (windows) (push) Successful in 7m32s
Release / Build latest.json (push) Successful in 5s
Completes the English-only standardization for code, comments, scripts and CI templates (UI/CLI-facing strings stay bilingual pt-BR/en, untouched). Covers the remaining crates/, apps/gui/ui/ and apps/gui/src-tauri/ comments, .gitea/ workflow and template comments, .githooks/ hooks, and the scripts/ source comments for the files already renamed in a prior commit (check.sh, generate-logo.py, install-hooks.sh). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VAyr8d7HuAdUGB6aA5xmDD
This commit is contained in:
1 parent
da212e6926
commit
6328220c60
129 files changed
+1961
-1834
No files matched your search
@@ -1,6 +1,6 @@
|
||||
//! BitLocker (Windows 7 em diante, inclusive BitLocker To Go): AES-CBC com ou sem difusor
|
||||
//! Elephant, e AES-XTS. Protetores: senha, chave de recuperação, chave de inicialização (.BEK),
|
||||
//! chave limpa (proteção suspensa) e chave do volume já conhecida. TPM não é suportado.
|
||||
//! BitLocker (Windows 7+, including BitLocker To Go): AES-CBC with or without Elephant
|
||||
//! diffuser, and AES-XTS. Protectors: password, recovery password, startup key (.BEK),
|
||||
//! clear key (suspended protection), and raw volume master key. TPM is not supported.
|
||||
|
||||
use super::*;
|
||||
use crate::source::{read_vec, SubSource};
|
||||
@@ -23,12 +23,12 @@ const GUID_EOW: [u8; 16] = [
|
||||
0x3b, 0x4d, 0xa8, 0x92, 0x80, 0xdd, 0x0e, 0x4d, 0x9e, 0x4e, 0xb1, 0xe3, 0x28, 0x4e, 0xae, 0xd8,
|
||||
];
|
||||
|
||||
/// Posição da tabela de deslocamentos FVE, se for BitLocker (normal ou To Go).
|
||||
/// Offset of the FVE metadata table if the volume is BitLocker (standard or To Go).
|
||||
fn offsets_pos(vbr: &[u8]) -> Option<usize> {
|
||||
if vbr.len() >= 11 && &vbr[3..11] == b"-FVE-FS-" {
|
||||
return Some(176);
|
||||
}
|
||||
// BitLocker To Go: parece FAT ("MSWIN4.1"), mas guarda o GUID do BitLocker no setor de boot.
|
||||
// BitLocker To Go: looks like FAT ("MSWIN4.1") but stores the BitLocker GUID in the boot sector.
|
||||
if vbr.len() >= 464 && (vbr[424..440] == GUID_NORMAL || vbr[424..440] == GUID_EOW) {
|
||||
return Some(440);
|
||||
}
|
||||
@@ -54,7 +54,7 @@ fn words(buf: &[u8]) -> Vec<u32> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Decifragem (ordem do dm-crypt do Linux): somas em ordem crescente.
|
||||
// Decryption (Linux dm-crypt order): additions in ascending order.
|
||||
fn diffuser_a_decrypt(d: &mut [u32]) {
|
||||
let n = d.len();
|
||||
for _ in 0..5 {
|
||||
@@ -77,7 +77,7 @@ fn diffuser_b_decrypt(d: &mut [u32]) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Decifra um setor AES-CBC + difusor Elephant (BitLocker Vista/7 sem XTS).
|
||||
/// Decrypts an AES-CBC + Elephant diffuser sector (BitLocker Vista/7 pre-XTS).
|
||||
pub fn elephant_decrypt(key: &AesAny, tweak: &AesAny, buf: &mut [u8], byte_off: u64) {
|
||||
let mut iv = [0u8; 16];
|
||||
iv[..8].copy_from_slice(&byte_off.to_le_bytes());
|
||||
@@ -89,7 +89,7 @@ pub fn elephant_decrypt(key: &AesAny, tweak: &AesAny, buf: &mut [u8], byte_off:
|
||||
for (i, w) in d.iter().enumerate() {
|
||||
buf[i * 4..i * 4 + 4].copy_from_slice(&w.to_le_bytes());
|
||||
}
|
||||
// Chave do setor: duas cifragens do deslocamento com a chave de ajuste.
|
||||
// Sector key: two encryptions of the byte offset with the tweak key.
|
||||
let mut k0 = [0u8; 16];
|
||||
k0[..8].copy_from_slice(&byte_off.to_le_bytes());
|
||||
let mut k1 = k0;
|
||||
@@ -106,7 +106,7 @@ pub fn elephant_decrypt(key: &AesAny, tweak: &AesAny, buf: &mut [u8], byte_off:
|
||||
|
||||
// ------------------------------------------------------------------ CCM
|
||||
|
||||
/// AES-CCM (nonce de 12 bytes, tag de 16): `blob` = tag cifrada (16) + dados cifrados.
|
||||
/// AES-CCM (12-byte nonce, 16-byte tag): `blob` = encrypted tag (16) + ciphertext.
|
||||
fn ccm_decrypt(key: &AesAny, nonce: &[u8], blob: &[u8]) -> Option<Vec<u8>> {
|
||||
if nonce.len() != 12 || blob.len() < 16 {
|
||||
return None;
|
||||
@@ -130,7 +130,7 @@ fn ccm_decrypt(key: &AesAny, nonce: &[u8], blob: &[u8]) -> Option<Vec<u8>> {
|
||||
let s = ctr(bi as u32 + 1);
|
||||
pt.extend(ch.iter().zip(s.iter()).map(|(a, b)| a ^ b));
|
||||
}
|
||||
// CBC-MAC sobre B0 + dados.
|
||||
// CBC-MAC over B0 + plaintext.
|
||||
let mut b0 = [0u8; 16];
|
||||
b0[0] = 0x3A;
|
||||
b0[1..13].copy_from_slice(nonce);
|
||||
@@ -146,7 +146,7 @@ fn ccm_decrypt(key: &AesAny, nonce: &[u8], blob: &[u8]) -> Option<Vec<u8>> {
|
||||
(x == tag).then_some(pt)
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- chaves
|
||||
// --------------------------------------------------------------- keys
|
||||
|
||||
fn stretch(initial: &[u8; 32], salt: &[u8]) -> [u8; 32] {
|
||||
let mut last = [0u8; 32];
|
||||
@@ -169,7 +169,7 @@ fn password_key(pw: &str, salt: &[u8]) -> [u8; 32] {
|
||||
stretch(&init, salt)
|
||||
}
|
||||
|
||||
/// Chave de recuperação: 8 blocos de 6 dígitos, cada um múltiplo de 11.
|
||||
/// Recovery password: 8 groups of 6 digits, each divisible by 11.
|
||||
fn recovery_key(rp: &str, salt: &[u8]) -> Option<[u8; 32]> {
|
||||
let digits: String = rp.chars().filter(|c| c.is_ascii_digit()).collect();
|
||||
if digits.len() != 48 {
|
||||
@@ -188,7 +188,7 @@ fn recovery_key(rp: &str, salt: &[u8]) -> Option<[u8; 32]> {
|
||||
Some(stretch(&init, salt))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- metadados
|
||||
// ----------------------------------------------------------- metadata
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Entry {
|
||||
@@ -250,7 +250,7 @@ fn read_fve(src: &dyn Source, offset: u64) -> Option<Fve> {
|
||||
}
|
||||
let version = le16(&h, 10);
|
||||
if version != 2 {
|
||||
return None; // Vista (versão 1) não suportado
|
||||
return None; // Vista (version 1) not supported
|
||||
}
|
||||
let encrypted_size = le64(&h, 16);
|
||||
let hdr_sectors = le32(&h, 28) as u64;
|
||||
@@ -293,7 +293,7 @@ fn read_fve(src: &dyn Source, offset: u64) -> Option<Fve> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Chave de um arquivo .BEK (chave de inicialização).
|
||||
/// Extracts the key from a .BEK startup key file.
|
||||
fn bek_key(file: &[u8]) -> Option<Vec<u8>> {
|
||||
if file.len() < 48 {
|
||||
return None;
|
||||
@@ -313,7 +313,7 @@ fn bek_key(file: &[u8]) -> Option<Vec<u8>> {
|
||||
|
||||
fn candidate_keys(v: &Vmk, secrets: &[Secret]) -> Vec<Vec<u8>> {
|
||||
let mut out: Vec<Vec<u8>> = vec![];
|
||||
// Chave limpa: o próprio protetor guarda a chave em claro.
|
||||
// Clear key: the protector itself stores the unencrypted key.
|
||||
if v.protection == 0 {
|
||||
for n in &v.nested {
|
||||
if n.vtype == 1 && n.data.len() >= 36 {
|
||||
@@ -350,7 +350,7 @@ fn decrypt_key_entry(key: &[u8], e: &Entry) -> Option<Vec<u8>> {
|
||||
return None;
|
||||
}
|
||||
let pt = ccm_decrypt(&aes, &e.data[..12], &e.data[12..])?;
|
||||
// payload = cabeçalho de entrada (8) + método (4) + chave
|
||||
// payload = entry header (8) + method (4) + key
|
||||
(pt.len() > 12).then(|| pt[12..].to_vec())
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ pub fn unlock(src: Arc<dyn Source>, secrets: &[Secret]) -> UnlockResult {
|
||||
}
|
||||
let bps = le16(&vbr, 11).max(512) as u64;
|
||||
let pos = offsets_pos(&vbr).unwrap_or(176);
|
||||
// Três cópias dos metadados; usa a primeira legível.
|
||||
// Three metadata copies exist; use the first valid one.
|
||||
let mut fve = None;
|
||||
let mut meta_offsets = vec![];
|
||||
for i in 0..3 {
|
||||
@@ -481,7 +481,7 @@ pub fn unlock(src: Arc<dyn Source>, secrets: &[Secret]) -> UnlockResult {
|
||||
let len = src.size();
|
||||
let mut cs = CryptSource::new(src.clone(), cipher, 0, len, bps);
|
||||
let mut patches = vec![];
|
||||
// Áreas de metadados FVE: o Windows não as expõe como dados.
|
||||
// FVE metadata regions: Windows masks them out as zeros.
|
||||
for off in meta_offsets {
|
||||
patches.push(Patch {
|
||||
at: off,
|
||||
@@ -492,7 +492,7 @@ pub fn unlock(src: Arc<dyn Source>, secrets: &[Secret]) -> UnlockResult {
|
||||
});
|
||||
}
|
||||
if fve.volume_header_size > 0 && fve.volume_header_offset > 0 {
|
||||
// O início do volume original foi movido para outro lugar e cifrado lá.
|
||||
// The original volume header was relocated and encrypted elsewhere.
|
||||
patches.push(Patch {
|
||||
at: fve.volume_header_offset,
|
||||
len: fve.volume_header_size,
|
||||
|
||||
Reference in new issue
Block a user