Skip to content

Commit bd6eccf

Browse files
committed
Add: Qualcomm User Data Encryption test script & Document
- Checks for fscryptctl binary presence - Creates a random sw encryption key - Applies and verifies encryption policy - Confirms functionality with a test file Signed-off-by: Bharani Bhuvanagiri <[email protected]>
1 parent 2ef8a98 commit bd6eccf

File tree

2 files changed

+308
-0
lines changed

2 files changed

+308
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
2+
SPDX-License-Identifier: BSD-3-Clause-Clear
3+
4+
# Qualcomm UserDataEncryption Functionality Test Script
5+
## Overview
6+
7+
The `UserDataEncryption` test script verifies basic filesystem encryption functionality. It generates a 64-byte key, adds it to the system, applies an encryption policy to a mount directory, and confirms the setup by creating and reading a test file. This ensures that key management and encryption policies work as expected.
8+
9+
## Features
10+
11+
- **Dependency Check**: Verifies the presence of the `fscryptctl` binary.
12+
- **Key Management**: Generates a 64-byte key and adds it to the filesystem.
13+
- **Encryption Policy**: Applies and verifies encryption policy on a mount directory.
14+
- **Functional Validation**: Creates and reads a test file to confirm encryption functionality.
15+
- **Automated Result Logging**: Outputs test results to a `.res` file for automated result collection.
16+
17+
## Prerequisites
18+
19+
Ensure the following components are present on the target device:
20+
21+
- `fscryptctl` binary available in `/data/`
22+
- Sufficient permissions to create and mount directories
23+
24+
## Directory Structure
25+
```
26+
Runner/
27+
├── suites/
28+
│ ├── Kernel/
29+
│ │ │ ├── baseport/
30+
│ │ │ │ ├── UserDataEncryption/
31+
│ │ │ │ │ ├── run.sh
32+
```
33+
## Usage
34+
35+
1. Copy repo to Target Device: Use scp to transfer the scripts from the host to the target device. The scripts should be copied to the ```/<user-defined-location>``` directory on the target device.
36+
37+
2. Verify Transfer: Ensure that the repo have been successfully copied to the ```/<user-defined-location>``` directory on the target device.
38+
39+
3. Run Scripts: Navigate to the ```/<user-defined-location>``` directory on the target device and execute the scripts as needed.
40+
41+
---
42+
Quick Example
43+
```
44+
git clone <this-repo>
45+
cd <this-repo>
46+
scp -r common Runner user@target_device_ip:/<user-defined-location>
47+
ssh user@target_device_ip
48+
cd /<user-defined-location>/Runner && ./run-test.sh UserDataEncryption
49+
50+
Sample output:
51+
sh-5.2# ./run-test.sh UserDataEncryption
52+
[Executing test case: UserDataEncryption] 2025-11-18 15:03:05 -
53+
[INFO] Running as root. Continuing...
54+
[INFO] 2025-11-18 15:03:05 - -----------------------------------------------------------------------------------------
55+
[INFO] 2025-11-18 15:03:05 - -------------------Starting UserDataEncryption Testcase----------------------------
56+
[INFO] 2025-11-18 15:03:05 - === Test Initialization ===
57+
[INFO] 2025-11-18 15:03:05 - Checking if dependency binary is available
58+
[INFO] 2025-11-18 15:03:05 - Temporary key file created: /tmp/tmp.yV9Fgr7z7T
59+
[INFO] 2025-11-18 15:03:05 - Generating 64-byte encryption key
60+
[INFO] 2025-11-18 15:03:05 - Creating unique mount folder under /mnt
61+
[INFO] 2025-11-18 15:03:05 - Created unique mount directory: /mnt/testing.pb1KIn
62+
[INFO] 2025-11-18 15:03:05 - Derived filesystem mount point: /var
63+
[INFO] 2025-11-18 15:03:05 - Adding encryption key to the filesystem
64+
[INFO] 2025-11-18 15:03:05 - No relevant, non-benign errors for modules [fscrypt] in recent dmesg.
65+
[INFO] 2025-11-18 15:03:05 - Key ID: 80ae0d678e52fb126ea6eda7d32861eb
66+
[INFO] 2025-11-18 15:03:05 - Checking key status
67+
[INFO] 2025-11-18 15:03:05 - Key Status: Present (user_count=1, added_by_self)
68+
[INFO] 2025-11-18 15:03:05 - Setting encryption policy on /mnt/testing.pb1KIn
69+
[INFO] 2025-11-18 15:03:06 - No relevant, non-benign errors for modules [fscrypt] in recent dmesg.
70+
[INFO] 2025-11-18 15:03:06 - Verifying encryption policy
71+
[INFO] 2025-11-18 15:03:06 - No relevant, non-benign errors for modules [fscrypt] in recent dmesg.
72+
[INFO] 2025-11-18 15:03:06 - Policy verification successful: Master key identifier matches key_id
73+
[INFO] 2025-11-18 15:03:06 - Creating test file in encrypted directory
74+
[INFO] 2025-11-18 15:03:06 - Reading test file
75+
[PASS] 2025-11-18 15:03:06 - UserDataEncryption : Test Passed
76+
[INFO] 2025-11-18 15:03:06 - -------------------Completed UserDataEncryption Testcase----------------------------
77+
[INFO] 2025-11-18 15:03:06 - Cleaning up mount directory: /mnt/testing.pb1KIn
78+
[INFO] 2025-11-18 15:03:06 - Deleted test file: /mnt/testing.pb1KIn/file.txt
79+
[INFO] 2025-11-18 15:03:06 - Removed mount directory: /mnt/testing.pb1KIn
80+
[PASS] 2025-11-18 15:03:06 - UserDataEncryption passed
81+
82+
[INFO] 2025-11-18 15:03:06 - ========== Test Summary ==========
83+
PASSED:
84+
UserDataEncryption
85+
86+
FAILED:
87+
None
88+
89+
SKIPPED:
90+
None
91+
[INFO] 2025-11-18 15:03:06 - ==================================
92+
```
93+
4. Results will be available in the `/<user-defined-location>/Runner/suites/Kernel/baseport/UserDataEncryption/` directory.
94+
95+
## Notes
96+
97+
- The script uses /data/UserDataEncryption for all operations.
98+
- Temporary files such as the encryption key are cleaned up after the test.
99+
- If any test fails, the script logs the error and exits with a failure code.
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
#!/bin/sh
2+
3+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
# SPDX-License-Identifier: BSD-3-Clause-Clear
5+
6+
# Ensure script runs as root
7+
if [ "$(id -u)" -ne 0 ]; then
8+
echo "[ERROR] This script must be run as root." >&2
9+
exit 1
10+
else
11+
echo "[INFO] Running as root. Continuing..."
12+
fi
13+
14+
# Robustly find and source init_env
15+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
16+
INIT_ENV=""
17+
SEARCH="$SCRIPT_DIR"
18+
while [ "$SEARCH" != "/" ]; do
19+
if [ -f "$SEARCH/init_env" ]; then
20+
INIT_ENV="$SEARCH/init_env"
21+
break
22+
fi
23+
SEARCH=$(dirname "$SEARCH")
24+
done
25+
26+
if [ -z "$INIT_ENV" ]; then
27+
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
28+
exit 1
29+
fi
30+
31+
if [ -z "$__INIT_ENV_LOADED" ]; then
32+
# shellcheck disable=SC1090
33+
. "$INIT_ENV"
34+
fi
35+
36+
# shellcheck disable=SC1090,SC1091
37+
. "$TOOLS/functestlib.sh"
38+
39+
FSCRYPTCTL="${FSCRYPTCTL:-fscryptctl}"
40+
TESTNAME="UserDataEncryption"
41+
test_path=$(find_test_case_by_name "$TESTNAME")
42+
43+
if [ -z "$test_path" ]; then
44+
log_fail "Path not found for $TESTNAME test. Falling back to SCRIPT_DIR: $SCRIPT_DIR"
45+
test_path="$SCRIPT_DIR"
46+
47+
echo "$TESTNAME FAIL" > "$SCRIPT_DIR/$TESTNAME.res"
48+
log_fail "$TESTNAME : Test case directory not found"
49+
exit 1
50+
fi
51+
52+
cd "$test_path" || {
53+
log_fail "Failed to change directory to $test_path"
54+
echo "$TESTNAME FAIL" > "$SCRIPT_DIR/$TESTNAME.res"
55+
exit 1
56+
}
57+
58+
res_file="./$TESTNAME.res"
59+
60+
# Globals that cleanup will use
61+
key_id=""
62+
KEY_FILE=""
63+
64+
cleanup() {
65+
if [ -n "$MOUNT_DIR" ] && [ "$MOUNT_DIR" != "/" ]; then
66+
log_info "Cleaning up mount directory: $MOUNT_DIR"
67+
if [ -f "$MOUNT_DIR/file.txt" ]; then
68+
rm -f "$MOUNT_DIR/file.txt" 2>/dev/null || true
69+
log_info "Deleted test file: $MOUNT_DIR/file.txt"
70+
fi
71+
72+
if [ -d "$MOUNT_DIR" ]; then
73+
rmdir "$MOUNT_DIR" 2>/dev/null || true
74+
log_info "Removed mount directory: $MOUNT_DIR"
75+
fi
76+
fi
77+
78+
if [ -n "$key_id" ]; then
79+
"$FSCRYPTCTL" remove_key "$key_id" "$FS_PATH" >/dev/null 2>&1 || true
80+
fi
81+
[ -n "$KEY_FILE" ] && rm -f "$KEY_FILE" 2>/dev/null || true
82+
}
83+
84+
# Run cleanup on normal exit, Ctrl-C, or SIGTERM
85+
trap cleanup EXIT INT TERM
86+
87+
log_info "-----------------------------------------------------------------------------------------"
88+
log_info "-------------------Starting $TESTNAME Testcase----------------------------"
89+
log_info "=== Test Initialization ==="
90+
91+
log_info "Checking if dependency binary is available"
92+
check_dependencies "$FSCRYPTCTL"
93+
94+
if ! command -v "$FSCRYPTCTL" >/dev/null 2>&1; then
95+
log_fail "$FSCRYPTCTL binary was not found. Skipping $TESTNAME."
96+
echo "$TESTNAME SKIP" > "$res_file"
97+
exit 0
98+
fi
99+
100+
# Create a secure temporary file for the key
101+
if KEY_FILE="$(mktemp)"; then
102+
log_info "Temporary key file created: $KEY_FILE"
103+
chmod 600 "$KEY_FILE"
104+
else
105+
log_fail "$TESTNAME : Failed to create temporary key file"
106+
echo "[ERROR] Failed to create temporary key file" >&2
107+
exit 1
108+
fi
109+
110+
# Step 1: Generate a 64-byte key
111+
log_info "Generating 64-byte encryption key"
112+
if ! head -c 64 /dev/urandom > "$KEY_FILE"; then
113+
log_fail "$TESTNAME : Failed to generate encryption key"
114+
echo "$TESTNAME FAIL" > "$res_file"
115+
exit 1
116+
fi
117+
118+
# Step 2: Create mount folder (this will create an unique folder under mnt)
119+
log_info "Creating unique mount folder under /mnt"
120+
MOUNT_DIR=$(mktemp -d /mnt/testing.XXXXXX)
121+
if [ ! -d "$MOUNT_DIR" ]; then
122+
log_fail "$TESTNAME : Failed to create mount directory"
123+
echo "$TESTNAME FAIL" > "$res_file"
124+
exit 1
125+
fi
126+
log_info "Created unique mount directory: $MOUNT_DIR"
127+
128+
129+
FS_PATH=$(df --output=target "$MOUNT_DIR" | tail -n 1)
130+
if [ -z "$FS_PATH" ]; then
131+
log_fail "$TESTNAME : Failed to determine filesystem mount point for $MOUNT_DIR"
132+
echo "$TESTNAME FAIL" > "$res_file"
133+
exit 1
134+
fi
135+
log_info "Derived filesystem mount point: $FS_PATH"
136+
137+
# Step 3: Add the key to the filesystem
138+
log_info "Adding encryption key to the filesystem"
139+
key_id=$("$FSCRYPTCTL" add_key "$FS_PATH" < "$KEY_FILE" 2>/dev/null)
140+
scan_dmesg_errors "$SCRIPT_DIR" "fscrypt" ""
141+
142+
if [ -z "$key_id" ]; then
143+
log_fail "$TESTNAME : Failed to add encryption key"
144+
echo "$TESTNAME FAIL" > "$res_file"
145+
exit 1
146+
fi
147+
148+
log_info "Key ID: $key_id"
149+
150+
# Step 4: Check key status
151+
log_info "Checking key status"
152+
status=$("$FSCRYPTCTL" key_status "$key_id" "$FS_PATH" 2>/dev/null)
153+
if [ -z "$status" ]; then
154+
log_fail "$TESTNAME : Failed to get key status"
155+
echo "$TESTNAME FAIL" > "$res_file"
156+
exit 1
157+
fi
158+
log_info "Key Status: $status"
159+
160+
if ! echo "$status" | grep -q "^Present"; then
161+
log_fail "$TESTNAME : Key is not usable (status: $status)"
162+
echo "$TESTNAME FAIL" > "$res_file"
163+
exit 1
164+
fi
165+
166+
167+
# Step 5: Set encryption policy
168+
log_info "Setting encryption policy on $MOUNT_DIR"
169+
170+
if ! "$FSCRYPTCTL" set_policy "$key_id" "$MOUNT_DIR"; then
171+
log_fail "$TESTNAME : Failed to set encryption policy"
172+
echo "$TESTNAME FAIL" > "$res_file"
173+
exit 1
174+
fi
175+
scan_dmesg_errors "$SCRIPT_DIR" "fscrypt" ""
176+
177+
178+
# Step 6: Verify policy
179+
log_info "Verifying encryption policy"
180+
policy_output=$("$FSCRYPTCTL" get_policy "$MOUNT_DIR" 2>/dev/null)
181+
scan_dmesg_errors "$SCRIPT_DIR" "fscrypt" ""
182+
183+
184+
policy_key=$(echo "$policy_output" | awk -F': ' '/Master key identifier/ {print $2}' | tr -d '[:space:]')
185+
186+
if [ "$policy_key" = "$key_id" ]; then
187+
log_info "Policy verification successful: Master key identifier matches key_id"
188+
else
189+
log_fail "$TESTNAME : Policy verification failed (expected $key_id, got $policy_key)"
190+
echo "$TESTNAME FAIL" > "$res_file"
191+
exit 1
192+
fi
193+
194+
# Step 7: Create and read a test file
195+
log_info "Creating test file in encrypted directory"
196+
echo "file" > "$MOUNT_DIR/file.txt"
197+
198+
log_info "Reading test file"
199+
file_content=$(cat "$MOUNT_DIR/file.txt")
200+
if [ "$file_content" = "file" ]; then
201+
log_pass "$TESTNAME : Test Passed"
202+
echo "$TESTNAME PASS" > "$res_file"
203+
else
204+
log_fail "$TESTNAME : Test Failed"
205+
echo "$TESTNAME FAIL" > "$res_file"
206+
exit 1
207+
fi
208+
209+
log_info "-------------------Completed $TESTNAME Testcase----------------------------"

0 commit comments

Comments
 (0)