Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
BitlockerDetection.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2018 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.modules.encryptiondetection;
20
21import org.sleuthkit.datamodel.TskCoreException;
22import org.sleuthkit.datamodel.Volume;
23
28final class BitlockerDetection {
29
30 private static final int BITLOCKER_BIOS_PARAMETER_BLOCK_SIZE = 0x54;
31 private static final byte[] BITLOCKER_SIGNATURE_BYTES = {'-', 'F', 'V', 'E', '-', 'F', 'S', '-'};
32 private static final int BITLOCKER_ADDRESS_SIGNATURE = 0x3;
33 private static final int BITLOCKER_ADDRESS_SECTORS_PER_CLUSTER = 0xD;
34 private static final int BITLOCKER_ADDRESS_RESERVED_CLUSTERS = 0xE;
35 private static final int BITLOCKER_ADDRESS_FAT_COUNT = 0x10;
36 private static final int BITLOCKER_ADDRESS_ROOT_ENTRIES = 0x11;
37 private static final int BITLOCKER_ADDRESS_SECTORS = 0x13;
38 private static final int BITLOCKER_ADDRESS_SECTORS_PER_FAT = 0x16;
39 private static final int BITLOCKER_ADDRESS_LARGE_SECTORS = 0x20;
40
44 private BitlockerDetection() {
45 }
46
57 static boolean isBitlockerVolume(Volume volume) throws TskCoreException {
58 /*
59 * Logic in this method is based on
60 * https://blogs.msdn.microsoft.com/si_team/2006/10/26/detecting-bitlocker/
61 */
62
63 boolean bitlockerVolume = false;
64
65 byte[] bpbArray = new byte[BITLOCKER_BIOS_PARAMETER_BLOCK_SIZE];
66 volume.read(bpbArray, 0, BITLOCKER_BIOS_PARAMETER_BLOCK_SIZE);
67
68 boolean signatureMatches = true;
69 for (int i = 0; i < BITLOCKER_SIGNATURE_BYTES.length; i++) {
70 if (bpbArray[BITLOCKER_ADDRESS_SIGNATURE + i] != BITLOCKER_SIGNATURE_BYTES[i]) {
71 signatureMatches = false;
72 break;
73 }
74 }
75
76 if (signatureMatches) {
77 switch ((int) bpbArray[BITLOCKER_ADDRESS_SECTORS_PER_CLUSTER]) {
78 case 0x01:
79 case 0x02:
80 case 0x04:
81 case 0x08:
82 case 0x10:
83 case 0x20:
84 case 0x40:
85 case 0x80:
86 short reservedClusters
87 = (short) ((bpbArray[BITLOCKER_ADDRESS_RESERVED_CLUSTERS] << 8)
88 | (bpbArray[BITLOCKER_ADDRESS_RESERVED_CLUSTERS + 1] & 0xFF));
89 byte fatCount
90 = bpbArray[BITLOCKER_ADDRESS_FAT_COUNT];
91 short rootEntries
92 = (short) ((bpbArray[BITLOCKER_ADDRESS_ROOT_ENTRIES] << 8)
93 | (bpbArray[BITLOCKER_ADDRESS_ROOT_ENTRIES + 1] & 0xFF));
94 short sectors
95 = (short) ((bpbArray[BITLOCKER_ADDRESS_SECTORS] << 8)
96 | (bpbArray[BITLOCKER_ADDRESS_SECTORS + 1] & 0xFF));
97 short sectorsPerFat
98 = (short) ((bpbArray[BITLOCKER_ADDRESS_SECTORS_PER_FAT] << 8)
99 | (bpbArray[BITLOCKER_ADDRESS_SECTORS_PER_FAT + 1] & 0xFF));
100 int largeSectors
101 = ((bpbArray[BITLOCKER_ADDRESS_LARGE_SECTORS] << 24)
102 | ((bpbArray[BITLOCKER_ADDRESS_LARGE_SECTORS + 1] & 0xFF) << 16)
103 | ((bpbArray[BITLOCKER_ADDRESS_LARGE_SECTORS + 2] & 0xFF) << 8)
104 | (bpbArray[BITLOCKER_ADDRESS_LARGE_SECTORS + 3] & 0xFF));
105
106 if (reservedClusters == 0 && fatCount == 0 && rootEntries == 0
107 && sectors == 0 && sectorsPerFat == 0 && largeSectors == 0) {
108 bitlockerVolume = true;
109 }
110
111 break;
112
113 default:
114 // Invalid value. This is not a Bitlocker volume.
115 }
116 }
117
118 return bitlockerVolume;
119 }
120}

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.