Skip to content

Commit 15a32da

Browse files
authored
Merge branch 'main' into dev/tdewey/verification-guide
2 parents 11c3012 + 1cb033f commit 15a32da

File tree

4 files changed

+122
-9
lines changed

4 files changed

+122
-9
lines changed

debian/postinst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ else
6767
CREATE TABLE devices_new($STATE_DB_SCHEMA);
6868
6969
-- Copy data from old table to new table (handling all columns)
70-
INSERT INTO devices_new($(echo $CURRENT_COLUMNS | sed 's/,$//'))
71-
SELECT $(echo $CURRENT_COLUMNS | sed 's/,$//')
70+
INSERT INTO devices_new($(echo "$CURRENT_COLUMNS" | sed 's/,$//'))
71+
SELECT $(echo "$CURRENT_COLUMNS" | sed 's/,$//')
7272
FROM devices;
7373
7474
-- Drop old table
@@ -95,6 +95,7 @@ fi
9595

9696
# Define the expected schema for manufacturing.db devices table
9797
# secure is set to 1 by default, as any prior release of rpi-sb-provisioner will have only offered secure provisioning
98+
# Security tracking fields default to NULL to distinguish between not-applied vs unknown state
9899
MFG_DB_SCHEMA="id integer primary key,
99100
boardname varchar(255) not null,
100101
serial char(8) not null,
@@ -109,6 +110,10 @@ MFG_DB_SCHEMA="id integer primary key,
109110
memory varchar(255) not null,
110111
manufacturer varchar(255) not null,
111112
secure integer not null DEFAULT 1,
113+
jtag_locked integer DEFAULT NULL,
114+
eeprom_write_protected integer DEFAULT NULL,
115+
pubkey_programmed integer DEFAULT NULL,
116+
signed_boot_enabled integer DEFAULT NULL,
112117
provision_ts timestamp default current_timestamp"
113118

114119
# Ensure WAL journal mode
@@ -126,7 +131,7 @@ else
126131
CURRENT_COLUMNS=$(sqlite3 "$MFG_DB_PATH" "PRAGMA table_info(devices);" | awk -F'|' '{print $2}' | tr '\n' ',')
127132

128133
# Check if any expected columns are missing
129-
for COL in id boardname serial eth_mac wifi_mac bt_mac mmc_size mmc_cid rpi_duid board_revision processor memory manufacturer secure provision_ts; do
134+
for COL in id boardname serial eth_mac wifi_mac bt_mac mmc_size mmc_cid rpi_duid board_revision processor memory manufacturer secure jtag_locked eeprom_write_protected pubkey_programmed signed_boot_enabled provision_ts; do
130135
if ! echo "$CURRENT_COLUMNS" | grep -q "$COL"; then
131136
echo "Migration needed: column $COL is missing from manufacturing.db devices table"
132137

@@ -135,8 +140,8 @@ else
135140
CREATE TABLE devices_new($MFG_DB_SCHEMA);
136141
137142
-- Copy data from old table to new table
138-
INSERT INTO devices_new($(echo $CURRENT_COLUMNS | sed 's/,$//'))
139-
SELECT $(echo $CURRENT_COLUMNS | sed 's/,$//')
143+
INSERT INTO devices_new($(echo "$CURRENT_COLUMNS" | sed 's/,$//'))
144+
SELECT $(echo "$CURRENT_COLUMNS" | sed 's/,$//')
140145
FROM devices;
141146
142147
-- Drop old table

docs/api_endpoints.adoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ The endpoint returns a JSON array where each element represents a provisioned de
4747
"memory": "2GB",
4848
"manufacturer": "Sony UK",
4949
"secure": "yes",
50+
"jtag_locked": "1",
51+
"eeprom_write_protected": "1",
52+
"pubkey_programmed": "1",
53+
"signed_boot_enabled": "1",
5054
"provision_ts": "2025-04-28 13:53:28"
5155
},
5256
...
@@ -72,6 +76,10 @@ The endpoint returns a JSON array where each element represents a provisioned de
7276
|memory|Device memory size (e.g., "2GB")
7377
|manufacturer|Device manufacturer
7478
|secure|Whether a device has been provisioned with a device unique identity
79+
|jtag_locked|JTAG debugging lock status (1=locked, 0=unlocked, null=unknown)
80+
|eeprom_write_protected|EEPROM write protection status (1=enabled, 0=disabled, null=unknown)
81+
|pubkey_programmed|Customer public key programming status (1=programmed, 0=not programmed, null=unknown)
82+
|signed_boot_enabled|Signed boot enablement status (1=enabled, 0=disabled, null=unknown)
7583
|provision_ts|Timestamp of when the device was provisioned
7684
|===
7785

host-support/manufacturing-data

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ metadata_gather() {
9191
sqlite3 "${RPI_SB_PROVISIONER_MANUFACTURING_DB}" "PRAGMA journal_mode=WAL;" > /dev/null 2>&1
9292

9393
# Define the schema for devices table
94+
# Security tracking fields default to NULL to distinguish between not-applied vs unknown state
9495
EXPECTED_SCHEMA="id integer primary key,
9596
boardname varchar(255) not null,
9697
serial char(8) not null,
@@ -105,6 +106,10 @@ metadata_gather() {
105106
memory varchar(255) not null,
106107
manufacturer varchar(255) not null,
107108
secure integer not null,
109+
jtag_locked integer DEFAULT NULL,
110+
eeprom_write_protected integer DEFAULT NULL,
111+
pubkey_programmed integer DEFAULT NULL,
112+
signed_boot_enabled integer DEFAULT NULL,
108113
provision_ts timestamp default current_timestamp"
109114

110115
# Check if the table exists
@@ -115,6 +120,41 @@ metadata_gather() {
115120
sqlite3 "${RPI_SB_PROVISIONER_MANUFACTURING_DB}" "CREATE TABLE devices($EXPECTED_SCHEMA);" > /dev/null 2>&1
116121
fi
117122

123+
# Determine security flags based on provisioning configuration
124+
# JTAG lock status: 1 if enabled, 0 if explicitly disabled, NULL if not configured
125+
JTAG_LOCKED_VALUE="NULL"
126+
if [ -n "${RPI_DEVICE_LOCK_JTAG}" ]; then
127+
JTAG_LOCKED_VALUE="1"
128+
elif [ "${SECURE}" = "1" ]; then
129+
# For secure provisioning, explicitly track that JTAG locking was not enabled
130+
JTAG_LOCKED_VALUE="0"
131+
fi
132+
133+
# EEPROM write protection status: 1 if enabled, 0 if explicitly disabled, NULL if not configured
134+
EEPROM_WP_VALUE="NULL"
135+
if [ -n "${RPI_DEVICE_EEPROM_WP_SET}" ]; then
136+
EEPROM_WP_VALUE="1"
137+
elif [ "${SECURE}" = "1" ]; then
138+
# For secure provisioning, explicitly track that EEPROM WP was not enabled
139+
EEPROM_WP_VALUE="0"
140+
fi
141+
142+
# Public key programming: 1 for secure provisioning, 0 for non-secure, NULL for unknown
143+
PUBKEY_PROGRAMMED_VALUE="NULL"
144+
if [ "${SECURE}" = "1" ]; then
145+
PUBKEY_PROGRAMMED_VALUE="1"
146+
elif [ "${SECURE}" = "0" ]; then
147+
PUBKEY_PROGRAMMED_VALUE="0"
148+
fi
149+
150+
# Signed boot: 1 for secure provisioning, 0 for non-secure, NULL for unknown
151+
SIGNED_BOOT_VALUE="NULL"
152+
if [ "${SECURE}" = "1" ]; then
153+
SIGNED_BOOT_VALUE="1"
154+
elif [ "${SECURE}" = "0" ]; then
155+
SIGNED_BOOT_VALUE="0"
156+
fi
157+
118158
# Insert new device data
119159
sqlite3 "${RPI_SB_PROVISIONER_MANUFACTURING_DB}" \
120160
"INSERT INTO devices( \
@@ -130,7 +170,11 @@ metadata_gather() {
130170
processor, \
131171
memory, \
132172
manufacturer, \
133-
secure \
173+
secure, \
174+
jtag_locked, \
175+
eeprom_write_protected, \
176+
pubkey_programmed, \
177+
signed_boot_enabled \
134178
) VALUES ( \
135179
'${BOARD_STR}', \
136180
'${TARGET_DEVICE_SERIAL}', \
@@ -144,7 +188,11 @@ metadata_gather() {
144188
'${PROCESSOR_STR}', \
145189
'${MEMORY_STR}', \
146190
'${MANUFACTURER_STR}', \
147-
'${SECURE}' \
191+
'${SECURE}', \
192+
${JTAG_LOCKED_VALUE}, \
193+
${EEPROM_WP_VALUE}, \
194+
${PUBKEY_PROGRAMMED_VALUE}, \
195+
${SIGNED_BOOT_VALUE} \
148196
);" > /dev/null 2>&1
149197
announce_stop "Manufacturing Database Insertion"
150198
fi

provisioner-service/src/views/manufacturing.csp

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,26 @@
134134
margin: 15px 0;
135135
border-left: 5px solid #d32f2f;
136136
}
137+
138+
.security-field {
139+
text-align: center;
140+
font-weight: bold;
141+
}
142+
143+
.security-enabled {
144+
color: #28a745;
145+
font-size: 14px;
146+
}
147+
148+
.security-disabled {
149+
color: #dc3545;
150+
font-size: 14px;
151+
}
152+
153+
.security-unknown {
154+
color: #6c757d;
155+
font-size: 14px;
156+
}
137157
</style>
138158
</head>
139159
<body>
@@ -178,6 +198,19 @@
178198
</div>
179199

180200
<script>
201+
// Function to format security field values
202+
function formatSecurityField(value) {
203+
if (value === null || value === undefined || value === '') {
204+
return '<span class="security-unknown">?</span>';
205+
} else if (value === '1') {
206+
return '<span class="security-enabled">✓</span>';
207+
} else if (value === '0') {
208+
return '<span class="security-disabled">✗</span>';
209+
} else {
210+
return '<span class="security-unknown">?</span>';
211+
}
212+
}
213+
181214
// Handle scroll indicator visibility
182215
function updateScrollIndicator() {
183216
const container = document.querySelector('.table-container');
@@ -252,6 +285,10 @@
252285
<th>Memory</th>
253286
<th>Manufacturer</th>
254287
<th>Secure</th>
288+
<th>JTAG Locked</th>
289+
<th>EEPROM WP</th>
290+
<th>Pubkey Prog.</th>
291+
<th>Signed Boot</th>
255292
</tr>
256293
</thead>
257294
<tbody>
@@ -276,13 +313,17 @@
276313
<td>${device.memory || ''}</td>
277314
<td>${device.manufacturer || ''}</td>
278315
<td>${device.secure || ''}</td>
316+
<td class="security-field">${formatSecurityField(device.jtag_locked)}</td>
317+
<td class="security-field">${formatSecurityField(device.eeprom_write_protected)}</td>
318+
<td class="security-field">${formatSecurityField(device.pubkey_programmed)}</td>
319+
<td class="security-field">${formatSecurityField(device.signed_boot_enabled)}</td>
279320
</tr>
280321
`;
281322
});
282323
} else {
283324
tableHtml += `
284325
<tr>
285-
<td colspan="15" class="no-devices">No manufacturing data available</td>
326+
<td colspan="19" class="no-devices">No manufacturing data available</td>
286327
</tr>
287328
`;
288329
}
@@ -333,7 +374,18 @@
333374
rows.forEach(row => {
334375
const rowData = [];
335376
row.querySelectorAll('td').forEach(cell => {
336-
rowData.push('"' + (cell.innerText || '') + '"');
377+
// For security fields, extract the symbol and convert to readable text
378+
let cellText = cell.innerText || '';
379+
if (cell.classList.contains('security-field')) {
380+
const span = cell.querySelector('span');
381+
if (span) {
382+
const symbol = span.innerText;
383+
if (symbol === '✓') cellText = 'Yes';
384+
else if (symbol === '✗') cellText = 'No';
385+
else if (symbol === '?') cellText = 'Unknown';
386+
}
387+
}
388+
rowData.push('"' + cellText + '"');
337389
});
338390
if (rowData.length > 1) { // Skip empty rows
339391
csvContent += rowData.join(',') + '\r\n';

0 commit comments

Comments
 (0)