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

ImpactDetails
ConfidentialityScope: Confidentiality

Cryptographic keys and proprietary algorithms exposed.
IntegrityScope: Integrity

Firmware and configuration can be modified during test.
Access ControlScope: 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.

  • 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

  1. MITRE Corporation. "CWE-1297: Unprotected Confidential Information on Device is Accessible by OSAT Vendors." https://cwe.mitre.org/data/definitions/1297.html
  2. NIST. "SP 800-193 Platform Firmware Resiliency Guidelines"
  3. Trusted Computing Group. "Hardware Security Guidelines"