Unprotected Confidential Information on Device is Accessible by OSAT Vendors
Description
Unprotected Confidential Information on Device is Accessible by OSAT Vendors occurs when a product fails to adequately protect confidential information from Outsourced Semiconductor Assembly and Test (OSAT) vendors who handle devices during pre-production stages. When chipmakers outsource assembly and testing rather than maintaining vertical integration, devices enter OSAT facilities in vulnerable pre-production states with accessible debug and test modes. This necessitates trusting OSAT partners, typically via non-disclosure agreements. However, OSAT vendors serve multiple customers, increasing accidental information-sharing risks. Additionally, IT security vulnerabilities or malicious insiders at OSAT facilities pose threats.
Risk
OSAT exposure has severe security implications. Master keys exposed to third parties. Debug capabilities accessible pre-production. Confidential algorithms disclosed. Trade secrets at risk. NDA alone insufficient protection. Multiple customers increase cross-contamination risk. Malicious insiders can extract secrets. One leaked key may compromise entire product generation. Medium likelihood but potentially catastrophic severity.
Solution
Ensure OSAT vendors access only minimal necessary information from test interfaces. Design systems so device-unlock requests apply only to specific parts, not entire product lines. Ensure that the product's non-volatile memory (NVM) is scrubbed of all confidential information and secrets before handing it over to an OSAT. Secure all OSAT-to-chipmaker communications. Implement per-device unique secrets rather than shared master keys. Use hardware security modules for sensitive operations.
Common Consequences
| Impact | Details |
|---|---|
| Confidentiality | Scope: Confidentiality Cryptographic keys and proprietary algorithms exposed. |
| Integrity | Scope: Integrity Firmware and configuration can be modified during test. |
| Access Control | Scope: Access Control, Authentication Debug credentials exposed enabling future attacks. |
Example Code
Vulnerable Code
// Vulnerable: Device with master key accessible to OSAT
module vulnerable_device_secrets (
input wire clk,
input wire rst_n,
input wire test_mode, // Active during OSAT testing
input wire [31:0] nvm_addr,
input wire nvm_read,
output reg [31:0] nvm_data
);
// VULNERABLE: Master key stored in NVM
// Same key for ALL devices in product line
reg [255:0] master_key;
// VULNERABLE: Debug unlock key also stored
reg [63:0] debug_unlock_key;
// VULNERABLE: Proprietary algorithm coefficients
reg [31:0] algo_coefficients [0:15];
// VULNERABLE: NVM contents readable in test mode
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
nvm_data <= 32'b0;
end else if (nvm_read) begin
// VULNERABLE: All NVM accessible during OSAT test
case (nvm_addr[7:0])
8'h00: nvm_data <= master_key[31:0]; // Key accessible!
8'h04: nvm_data <= master_key[63:32];
8'h08: nvm_data <= master_key[95:64];
// ... more key bytes accessible
8'h20: nvm_data <= debug_unlock_key[31:0];
8'h24: nvm_data <= debug_unlock_key[63:32];
8'h40: nvm_data <= algo_coefficients[nvm_addr[5:2]];
default: nvm_data <= 32'b0;
endcase
end
end
// VULNERABLE: No protection during test mode
// OSAT can read all secrets via test interface
endmodule
// Vulnerable: Shared master key provisioning
module vulnerable_key_provisioning (
input wire clk,
input wire rst_n,
input wire provision_enable,
input wire [255:0] master_key_input,
output reg [255:0] device_key
);
// VULNERABLE: Same master key programmed to all devices
// If OSAT extracts key from one device, all are compromised
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
device_key <= 256'b0;
end else if (provision_enable) begin
// VULNERABLE: Direct master key storage
device_key <= master_key_input;
end
end
endmodule
// Vulnerable: Pre-production device with exposed secrets
#include <stdint.h>
#include <string.h>
// VULNERABLE: Master key embedded in firmware
// This firmware image goes to OSAT
static const uint8_t MASTER_KEY[32] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
};
// VULNERABLE: Debug unlock code in firmware
static const uint64_t DEBUG_UNLOCK = 0xDEADBEEFCAFEBABE;
// VULNERABLE: Test function exposes secrets
void vulnerable_test_interface(uint32_t command, uint8_t* response) {
switch (command) {
case 0x01: // Read master key
// VULNERABLE: Key readable via test command
memcpy(response, MASTER_KEY, sizeof(MASTER_KEY));
break;
case 0x02: // Read debug unlock
// VULNERABLE: Debug code readable
memcpy(response, &DEBUG_UNLOCK, sizeof(DEBUG_UNLOCK));
break;
case 0x03: // Memory dump
// VULNERABLE: Full memory access for "testing"
dump_memory(response);
break;
default:
break;
}
}
// VULNERABLE: NVM not scrubbed before OSAT handoff
typedef struct {
uint8_t master_key[32]; // VULNERABLE: In cleartext
uint8_t debug_key[8]; // VULNERABLE: In cleartext
uint8_t device_certificate[512];
uint32_t serial_number;
} nvm_contents_t;
void vulnerable_prepare_for_osat(void) {
// VULNERABLE: No scrubbing of sensitive data
// Device goes to OSAT with all secrets intact
}
Fixed Code
// Fixed: Device with protected secrets for OSAT handoff
module secure_device_secrets (
input wire clk,
input wire rst_n,
input wire test_mode,
input wire production_mode, // Fused after OSAT
input wire [31:0] nvm_addr,
input wire nvm_read,
output reg [31:0] nvm_data
);
// FIXED: Per-device unique key derived from PUF
// Not stored in NVM, generated at runtime
wire [255:0] device_unique_key;
// FIXED: Master key not stored on device
// Master key stays in secure facility HSM
// FIXED: Test-mode restrictions
reg [31:0] public_test_data [0:15]; // Only non-sensitive test data
// FIXED: Secure key storage - not readable via test interface
// Keys stored in isolated, non-readable block
secure_key_block u_key_block (
.clk(clk),
.rst_n(rst_n),
.production_mode(production_mode),
.device_key(device_unique_key)
);
// FIXED: Test mode only accesses non-sensitive data
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
nvm_data <= 32'b0;
end else if (nvm_read) begin
if (test_mode && !production_mode) begin
// FIXED: Only public test data accessible during OSAT
if (nvm_addr < 32'h40) begin
nvm_data <= public_test_data[nvm_addr[5:2]];
end else begin
nvm_data <= 32'b0; // Sensitive areas return zero
end
end else if (production_mode) begin
// Production mode - different access rules
// Key still not directly readable
nvm_data <= read_production_nvm(nvm_addr);
end else begin
nvm_data <= 32'b0;
end
end
end
endmodule
// Fixed: Per-device unique key derivation
module secure_key_provisioning (
input wire clk,
input wire rst_n,
input wire provision_enable,
input wire [127:0] diversification_data, // Unique per device
input wire production_fuse,
output wire [255:0] device_unique_key
);
// FIXED: PUF-based unique key generation
wire [255:0] puf_response;
puf_block u_puf (
.clk(clk),
.rst_n(rst_n),
.challenge(diversification_data),
.response(puf_response)
);
// FIXED: Device key derived from PUF - unique per device
// Even if OSAT extracts this device's key, other devices are safe
kdf_block u_kdf (
.clk(clk),
.rst_n(rst_n),
.puf_secret(puf_response),
.diversifier(diversification_data),
.derived_key(device_unique_key)
);
// FIXED: Key only available after production fuse is set
// During OSAT, key derivation is disabled
endmodule
// Fixed: Secure NVM scrubbing before OSAT
module secure_nvm_scrub (
input wire clk,
input wire rst_n,
input wire scrub_enable,
input wire scrub_complete,
output reg nvm_write_enable,
output reg [31:0] nvm_write_addr,
output reg [31:0] nvm_write_data
);
// FIXED: Scrub all sensitive regions before OSAT handoff
localparam SCRUB_IDLE = 2'b00;
localparam SCRUB_ACTIVE = 2'b01;
localparam SCRUB_DONE = 2'b10;
reg [1:0] state;
reg [15:0] scrub_counter;
// Sensitive address ranges to scrub
localparam SENSITIVE_START = 32'h0000_1000;
localparam SENSITIVE_END = 32'h0000_2000;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= SCRUB_IDLE;
scrub_counter <= 16'b0;
nvm_write_enable <= 1'b0;
end else begin
case (state)
SCRUB_IDLE: begin
if (scrub_enable) begin
state <= SCRUB_ACTIVE;
scrub_counter <= 16'b0;
end
end
SCRUB_ACTIVE: begin
// FIXED: Overwrite all sensitive NVM locations
nvm_write_enable <= 1'b1;
nvm_write_addr <= SENSITIVE_START + {scrub_counter, 2'b00};
nvm_write_data <= 32'h0000_0000; // Or random pattern
if (nvm_write_addr >= SENSITIVE_END) begin
state <= SCRUB_DONE;
nvm_write_enable <= 1'b0;
end else begin
scrub_counter <= scrub_counter + 1;
end
end
SCRUB_DONE: begin
nvm_write_enable <= 1'b0;
// Stay in done state until reset
end
endcase
end
end
endmodule
// Fixed: Secure handling for OSAT handoff
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
// FIXED: No master key in firmware
// Master key operations done via secure HSM communication
// FIXED: Per-device unique key derivation
typedef struct {
uint8_t puf_response[32];
uint8_t diversifier[16];
} key_derivation_input_t;
// FIXED: Minimal test interface
void secure_test_interface(uint32_t command, uint8_t* response) {
switch (command) {
case 0x01: // Device ID only
// FIXED: Only non-sensitive identifiers
get_device_id(response);
break;
case 0x02: // Basic functionality test
// FIXED: Test result, not internal data
response[0] = run_basic_test() ? 0x01 : 0x00;
break;
case 0x03: // Manufacturing test pattern
// FIXED: Known test patterns, not secrets
generate_test_pattern(response);
break;
// FIXED: No commands to read keys or sensitive data
default:
memset(response, 0, 64);
break;
}
}
// FIXED: Scrub before OSAT handoff
void secure_prepare_for_osat(void) {
// FIXED: Scrub all sensitive NVM regions
scrub_nvm_region(SENSITIVE_KEY_REGION_START, SENSITIVE_KEY_REGION_SIZE);
scrub_nvm_region(DEBUG_KEY_REGION_START, DEBUG_KEY_REGION_SIZE);
// FIXED: Disable sensitive features
disable_secure_debug();
disable_key_export();
// FIXED: Verify scrub completed
if (!verify_scrub_complete()) {
// Halt - don't proceed to OSAT with secrets
enter_lockdown_mode();
}
// FIXED: Set pre-OSAT state indicator
set_device_state(DEVICE_STATE_PRE_OSAT);
}
// FIXED: Post-OSAT provisioning
void secure_post_osat_provision(const uint8_t* device_diversifier) {
// FIXED: Verify device came back from OSAT
if (get_device_state() != DEVICE_STATE_POST_OSAT) {
return;
}
// FIXED: Generate unique device key using PUF
uint8_t puf_response[32];
get_puf_response(puf_response);
// FIXED: Derive unique key (never stored in raw form)
derive_device_key(puf_response, device_diversifier);
// FIXED: Set production state
blow_production_fuse();
set_device_state(DEVICE_STATE_PRODUCTION);
}
// FIXED: Verify no sensitive data before OSAT
bool verify_ready_for_osat(void) {
// Check all sensitive regions are scrubbed
if (!is_region_scrubbed(SENSITIVE_KEY_REGION_START, SENSITIVE_KEY_REGION_SIZE)) {
return false;
}
// Check debug is disabled
if (is_debug_enabled()) {
return false;
}
// Check no certificates provisioned
if (has_device_certificate()) {
return false;
}
return true;
}
CVE Examples
- CVE-2019-14615: Confidential data accessible through test interfaces during manufacturing.
- CVE-2020-8708: Debug interfaces exposed sensitive information to third-party testing facilities.
Related CWEs
- CWE-285: Improper Authorization (parent)
- CWE-1195: Manufacturing and Life Cycle Management Concerns (category)
- CWE-1244: Internal Asset Exposed to Unsafe Debug Access (related)
- CWE-1263: Improper Physical Access Control (related)
References
- MITRE Corporation. "CWE-1297: Unprotected Confidential Information on Device is Accessible by OSAT Vendors." https://cwe.mitre.org/data/definitions/1297.html
- NIST. "SP 800-193 Platform Firmware Resiliency Guidelines"
- Trusted Computing Group. "Hardware Security Guidelines"