Product Released in Non-Release Configuration
Description
Product Released in Non-Release Configuration occurs when a product reaches market in a pre-production or manufacturing configuration rather than a finalized release state. Pre-production and manufacturing stages include extensive debug capabilities that create security vulnerabilities including ability to bypass cryptographic checks (authentication, authorization, integrity), access to read/write/modify internal state (registers, memory), system configuration alteration capabilities, and hidden commands exposing intellectual property. When the "Manufacturing Complete" marker is not activated before release, the system remains vulnerable.
Risk
Non-release configuration has severe security implications. Debug interfaces remain accessible. Authentication can be bypassed. Memory can be freely read and written. Internal state can be modified. Cryptographic checks can be disabled. Intellectual property may be exposed. System configuration can be altered. Unauthorized code can be executed. Complete system compromise is possible.
Solution
Establish a Manufacturing Complete marker. Ensure the marker updates at manufacturing completion through mechanisms like fuse activation. Verify release configuration before shipping. Implement checks that enforce production mode. Test that debug features are properly disabled in release. Document and follow secure manufacturing procedures.
Common Consequences
| Impact | Details |
|---|---|
| Confidentiality | Scope: Confidentiality Read Memory - Manufacturing mode allows unrestricted memory access including secrets. |
| Integrity | Scope: Integrity Modify Memory - Debug capabilities allow arbitrary memory modification. |
| Access Control | Scope: Access Control Bypass Protection Mechanism - Security checks can be bypassed in manufacturing mode. |
| Authentication | Scope: Authentication Bypass Authentication - Authentication may be disabled in manufacturing mode. |
Example Code
Vulnerable Code
// Vulnerable: Device without manufacturing complete check
module vulnerable_security_controller (
input wire clk,
input wire reset_n,
// Debug interface
input wire debug_request,
input wire [31:0] debug_addr,
input wire [31:0] debug_data,
input wire debug_write,
output reg [31:0] debug_read_data,
output reg debug_granted,
// Manufacturing fuse
input wire manufacturing_complete_fuse,
// Secure boot
input wire boot_request,
output reg boot_allowed
);
// VULNERABLE: Manufacturing complete fuse is NOT checked
// Product ships with fuse unblown (manufacturing_complete_fuse = 0)
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
debug_granted <= 1'b0;
boot_allowed <= 1'b0;
end
else begin
// VULNERABLE: Debug always granted - no fuse check
// In production, this should require manufacturing_complete_fuse = 0
if (debug_request) begin
// Should check: !manufacturing_complete_fuse
debug_granted <= 1'b1;
// Unrestricted memory access
if (debug_write) begin
memory[debug_addr] <= debug_data;
end
else begin
debug_read_data <= memory[debug_addr];
end
end
// VULNERABLE: Secure boot can be bypassed
if (boot_request) begin
// Should enforce signature check in production
// But manufacturing mode allows bypass
boot_allowed <= 1'b1; // Always allowed!
end
end
end
endmodule
// Vulnerable: UART debug enabled in production
module vulnerable_uart_debug (
input wire clk,
input wire reset_n,
input wire uart_rx,
output wire uart_tx,
// Manufacturing mode
input wire mfg_mode_fuse
);
// VULNERABLE: Manufacturing mode fuse not blown
// mfg_mode_fuse = 0 means manufacturing mode active
// Debug commands available
parameter CMD_READ_MEM = 8'h01;
parameter CMD_WRITE_MEM = 8'h02;
parameter CMD_DUMP_SECRETS = 8'h03;
parameter CMD_BYPASS_AUTH = 8'h04;
reg [7:0] command;
reg [31:0] address;
reg [31:0] data;
always @(posedge clk) begin
// VULNERABLE: No check for production mode
// These commands work even after product ships
case (command)
CMD_READ_MEM: begin
// Read any memory location
uart_send(memory[address]);
end
CMD_WRITE_MEM: begin
// Write any memory location
memory[address] <= data;
end
CMD_DUMP_SECRETS: begin
// VULNERABLE: Dump all secrets
uart_send(encryption_key);
uart_send(private_key);
end
CMD_BYPASS_AUTH: begin
// VULNERABLE: Skip authentication
authenticated <= 1'b1;
end
endcase
end
endmodule
// Vulnerable: Software without manufacturing check
#include <stdint.h>
#define FUSE_REG_ADDR 0x40000000
#define MFG_COMPLETE_BIT 0
// VULNERABLE: Manufacturing complete fuse not checked
bool is_manufacturing_mode(void) {
uint32_t fuse_value = *(volatile uint32_t*)FUSE_REG_ADDR;
// Fuse not blown = manufacturing mode (bit 0 = 0)
return (fuse_value & (1 << MFG_COMPLETE_BIT)) == 0;
}
void vulnerable_boot(void) {
// VULNERABLE: Debug enabled regardless of manufacturing status
enable_debug_uart();
enable_jtag();
// VULNERABLE: Skip signature check in manufacturing mode
if (is_manufacturing_mode()) {
// This code path should not exist in shipping product!
execute_unsigned_firmware();
}
else {
if (verify_signature()) {
execute_firmware();
}
else {
halt();
}
}
// Problem: Product shipped with fuse not blown
// is_manufacturing_mode() returns true
// Attacker can execute unsigned firmware!
}
void vulnerable_handle_debug_command(uint8_t cmd, uint32_t* args) {
// VULNERABLE: No manufacturing mode check
// These commands work on shipped products
switch (cmd) {
case DEBUG_CMD_READ_MEM:
// Read any memory
uart_send(*(volatile uint32_t*)args[0]);
break;
case DEBUG_CMD_WRITE_MEM:
// Write any memory
*(volatile uint32_t*)args[0] = args[1];
break;
case DEBUG_CMD_EXTRACT_KEY:
// VULNERABLE: Extract cryptographic key
uart_send_buffer(crypto_key, 32);
break;
case DEBUG_CMD_DISABLE_SECURITY:
// VULNERABLE: Disable all security
security_enabled = false;
break;
}
}
Fixed Code
// Fixed: Device with proper manufacturing complete enforcement
module secure_security_controller (
input wire clk,
input wire reset_n,
// Debug interface
input wire debug_request,
input wire [31:0] debug_addr,
input wire [31:0] debug_data,
input wire debug_write,
output reg [31:0] debug_read_data,
output reg debug_granted,
output reg debug_denied,
// Manufacturing fuse (1 = manufacturing complete, 0 = manufacturing)
input wire manufacturing_complete_fuse,
// Secure boot
input wire boot_request,
input wire signature_valid,
output reg boot_allowed,
output reg boot_denied
);
// FIXED: Determine production vs manufacturing mode
wire is_production = manufacturing_complete_fuse;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
debug_granted <= 1'b0;
debug_denied <= 1'b0;
boot_allowed <= 1'b0;
boot_denied <= 1'b0;
end
else begin
debug_granted <= 1'b0;
debug_denied <= 1'b0;
boot_denied <= 1'b0;
// FIXED: Debug only available in manufacturing mode
if (debug_request) begin
if (!is_production) begin
// Manufacturing mode - debug allowed
debug_granted <= 1'b1;
// ... debug operations
end
else begin
// FIXED: Production mode - debug denied
debug_denied <= 1'b1;
debug_read_data <= 32'hDEADBEEF;
end
end
// FIXED: Secure boot enforced in production
if (boot_request) begin
if (is_production) begin
// Production mode - require valid signature
if (signature_valid) begin
boot_allowed <= 1'b1;
end
else begin
boot_denied <= 1'b1;
end
end
else begin
// Manufacturing mode - may allow unsigned boot
// with appropriate warnings
boot_allowed <= 1'b1;
end
end
end
end
endmodule
// Fixed: UART with manufacturing mode enforcement
module secure_uart_debug (
input wire clk,
input wire reset_n,
input wire uart_rx,
output wire uart_tx,
input wire mfg_mode_fuse, // 1 = production, 0 = manufacturing
output reg mfg_mode_violation
);
wire is_production = mfg_mode_fuse;
reg [7:0] command;
reg command_valid;
// FIXED: Debug command handling with mode check
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
mfg_mode_violation <= 1'b0;
end
else if (command_valid) begin
mfg_mode_violation <= 1'b0;
// FIXED: Block all debug commands in production
if (is_production) begin
// Log violation attempt
mfg_mode_violation <= 1'b1;
// Return error to UART
uart_send_error();
end
else begin
// Manufacturing mode - commands allowed
case (command)
CMD_READ_MEM: uart_send(memory[address]);
CMD_WRITE_MEM: memory[address] <= data;
// Note: Sensitive commands may still be restricted
CMD_DUMP_SECRETS: begin
// Even in mfg mode, require additional auth
if (mfg_authenticated) begin
// Allowed
end
else begin
uart_send_error();
end
end
endcase
end
end
end
endmodule
// Fixed: Manufacturing complete verification
module mfg_complete_checker (
input wire clk,
input wire reset_n,
input wire mfg_fuse,
input wire check_enable,
output reg mfg_complete,
output reg check_failed
);
// FIXED: Verify fuse is properly blown
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
mfg_complete <= 1'b0;
check_failed <= 1'b0;
end
else if (check_enable) begin
// Read fuse multiple times to ensure reliability
if (mfg_fuse && mfg_fuse && mfg_fuse) begin
mfg_complete <= 1'b1;
check_failed <= 1'b0;
end
else if (!mfg_fuse && !mfg_fuse && !mfg_fuse) begin
mfg_complete <= 1'b0;
check_failed <= 1'b0;
end
else begin
// Inconsistent reads - potential tampering
check_failed <= 1'b1;
end
end
end
endmodule
// Fixed: Software with proper manufacturing mode handling
#include <stdint.h>
#include <stdbool.h>
#define FUSE_REG_ADDR 0x40000000
#define MFG_COMPLETE_BIT 0
// FIXED: Comprehensive manufacturing mode check
static bool is_manufacturing_mode(void) {
volatile uint32_t* fuse_reg = (volatile uint32_t*)FUSE_REG_ADDR;
// FIXED: Read multiple times to prevent glitching
uint32_t read1 = *fuse_reg;
uint32_t read2 = *fuse_reg;
uint32_t read3 = *fuse_reg;
// All reads must match
if (read1 != read2 || read2 != read3) {
// Inconsistent - assume production (secure default)
log_security_event("Fuse read inconsistency - assuming production");
return false;
}
// Fuse blown (bit = 1) = production mode
return (read1 & (1 << MFG_COMPLETE_BIT)) == 0;
}
void secure_boot(void) {
bool mfg_mode = is_manufacturing_mode();
if (mfg_mode) {
// Manufacturing mode
log_info("Manufacturing mode active");
enable_debug_uart();
enable_jtag();
}
else {
// FIXED: Production mode - disable debug
disable_debug_uart();
disable_jtag();
lock_debug_interface(); // Prevent re-enabling
}
// FIXED: Secure boot always required in production
if (!mfg_mode) {
if (!verify_signature()) {
log_error("Signature verification failed");
enter_secure_halt(); // Don't boot!
return;
}
}
execute_firmware();
}
// FIXED: Debug commands only in manufacturing mode
int secure_handle_debug_command(uint8_t cmd, uint32_t* args) {
// FIXED: Check manufacturing mode for every command
if (!is_manufacturing_mode()) {
log_security_event("Debug command blocked in production mode");
return -EPERM;
}
// Additional authentication even in manufacturing
if (!is_debug_authenticated()) {
log_security_event("Debug authentication required");
return -EAUTH;
}
switch (cmd) {
case DEBUG_CMD_READ_MEM:
// Limited read in manufacturing
if (!is_address_debug_readable(args[0])) {
return -EACCES;
}
uart_send(*(volatile uint32_t*)args[0]);
break;
case DEBUG_CMD_WRITE_MEM:
if (!is_address_debug_writable(args[0])) {
return -EACCES;
}
*(volatile uint32_t*)args[0] = args[1];
break;
case DEBUG_CMD_EXTRACT_KEY:
// FIXED: Never allow key extraction, even in manufacturing
log_security_event("Key extraction attempted");
return -EPERM;
default:
return -EINVAL;
}
return 0;
}
// FIXED: Manufacturing finalization procedure
int finalize_manufacturing(void) {
// Verify device is ready for production
if (!run_self_tests()) {
return -EFAULT;
}
// FIXED: Blow manufacturing complete fuse
if (blow_mfg_complete_fuse() != 0) {
log_error("Failed to blow manufacturing complete fuse");
return -EIO;
}
// FIXED: Verify fuse is blown
if (is_manufacturing_mode()) {
log_error("Manufacturing mode still active after fuse blow");
return -EFAULT;
}
// FIXED: Verify debug is disabled
if (is_debug_accessible()) {
log_error("Debug still accessible after finalization");
return -EFAULT;
}
log_info("Manufacturing finalization complete");
return 0;
}
CVE Examples
- CVE-2019-13945: SIMATIC S7-1200/S7-200 manufacturing access mode enabled diagnostics via UART
- CVE-2018-4251: Intel chipset laptops discovered operating in Manufacturing Mode with debug capabilities enabled
Related CWEs
- CWE-693: Protection Mechanism Failure (parent)
- CWE-1191: On-Chip Debug/Test Interface With Improper Access Control (related)
- CWE-489: Active Debug Code (related)
- CAPEC-439: Manipulation During Distribution (attack pattern)
References
- MITRE Corporation. "CWE-1269: Product Released in Non-Release Configuration." https://cwe.mitre.org/data/definitions/1269.html
- Intel. "Manufacturing Mode Documentation"
- Siemens. "Industrial Control System Security Advisories"