| 1592 | } |
| 1593 | |
| 1594 | fn validate_single_luks2_header(mut reader: impl std::io::Read, hdr_ind: u64) -> Result<()> { |
| 1595 | let mut hdr_data = vec![0u8; 4096]; |
| 1596 | reader |
| 1597 | .read_exact(&mut hdr_data) |
| 1598 | .context("Failed to read LUKS header")?; |
| 1599 | let header = |
| 1600 | LuksHeader::read_from(&mut &hdr_data[..]).context("Failed to decode LUKS header")?; |
| 1601 | let LuksHeader { |
| 1602 | magic, |
| 1603 | version, |
| 1604 | hdr_size, |
| 1605 | seqid: _, |
| 1606 | label, |
| 1607 | csum_alg, |
| 1608 | salt: _, |
| 1609 | uuid: _, |
| 1610 | subsystem, |
| 1611 | hdr_offset, |
| 1612 | csum: _, |
| 1613 | .. |
| 1614 | } = header; |
| 1615 | |
| 1616 | let expected_magic = match hdr_ind { |
| 1617 | 0 => [76, 85, 75, 83, 186, 190], |
| 1618 | 1 => [83, 75, 85, 76, 186, 190], |
| 1619 | _ => bail!("Invalid LUKS header index: {hdr_ind}"), |
| 1620 | }; |
| 1621 | if magic != expected_magic { |
| 1622 | bail!("Invalid LUKS magic: {magic:?}"); |
| 1623 | } |
| 1624 | if version != 2 { |
| 1625 | bail!("Invalid LUKS version: {version}"); |
| 1626 | } |
| 1627 | if label != [0; 48] { |
| 1628 | bail!("Invalid LUKS label: {:?}", label); |
| 1629 | } |
| 1630 | if csum_alg != const_pad!(b"sha256", 32) { |
| 1631 | bail!("Invalid LUKS checksum algorithm"); |
| 1632 | } |
| 1633 | if subsystem != [0; 48] { |
| 1634 | bail!("Invalid LUKS subsystem"); |
| 1635 | } |
| 1636 | if hdr_offset != hdr_ind * hdr_size { |
| 1637 | bail!("Invalid LUKS header offset: {hdr_offset}"); |
| 1638 | } |
| 1639 | if !(4096..=1024 * 1024 * 16).contains(&hdr_size) { |
| 1640 | bail!("Invalid LUKS header size: {hdr_size}"); |
| 1641 | } |
| 1642 | |
| 1643 | // Check JSON |
| 1644 | let json_size = hdr_size - 4096; |
| 1645 | let mut jsn_data = vec![0u8; json_size as usize]; |
| 1646 | reader |
| 1647 | .read_exact(&mut jsn_data) |
| 1648 | .context("Failed to read LUKS JSON")?; |
| 1649 | let json_end = jsn_data |
| 1650 | .iter() |
| 1651 | .position(|&b| b == 0) |