Missing Support for Security Features in On-chip Fabrics or Buses
Description
Missing Support for Security Features in On-chip Fabrics or Buses occurs when on-chip fabrics or buses either do not support or are not configured to support privilege separation or other security features, such as access control. The weakness manifests when on-chip communication infrastructure lacks mechanisms to transport security attributes (privilege levels, identity, access control data) between bus masters and slaves. Even when supported, these features may remain unconfigured during RTL generation, rendering them ineffective and leaving security-critical communications unprotected.
Risk
Missing security features in fabrics has severe implications. No privilege separation possible. Security attributes not transported. Access control impossible to enforce. All masters appear equally trusted. Protected peripherals accessible by anyone. Secure and non-secure worlds cannot be separated. TrustZone-style isolation fails. Side-channel attacks between domains. Medium likelihood when using protocols with optional security or during cost-optimized designs.
Solution
Implement security checks at fabric bridges or intermediate modules. Segregate unsecured buses from security-critical peripherals. Connect security-sensitive assets to buses supporting security features. Configure optional security signals (e.g., MReqInfo/SRespInfo in OCP, AxPROT in AXI) during RTL generation. Perform architecture and design reviews to ensure fabric specifications include required security signals.
Common Consequences
| Impact | Details |
|---|---|
| Access Control | Scope: Access Control Unable to enforce privilege separation or access restrictions. |
| Confidentiality | Scope: Confidentiality Unauthorized memory read access due to missing security attributes. |
| Integrity | Scope: Integrity Memory modification possible when access control cannot be enforced. |
| Availability | Scope: Availability Denial of service through unauthorized access to critical resources. |
Example Code
Vulnerable Code
// Vulnerable: APB bus without sufficient security signals
module vulnerable_apb_interconnect (
input wire clk,
input wire rst_n,
// Master interface
input wire [31:0] master_paddr,
input wire [31:0] master_pwdata,
input wire master_pwrite,
input wire master_psel,
input wire master_penable,
// VULNERABLE: No PPROT signal!
// APB2 has limited PPROT (only 3 bits)
// Slave 0 - Secure peripheral
output reg [31:0] slave0_paddr,
output reg [31:0] slave0_pwdata,
output reg slave0_pwrite,
output reg slave0_psel,
output reg slave0_penable,
// Slave 1 - Normal peripheral
output reg [31:0] slave1_paddr,
output reg [31:0] slave1_pwdata,
output reg slave1_pwrite,
output reg slave1_psel,
output reg slave1_penable
);
// Address decode
wire select_slave0 = (master_paddr[31:16] == 16'h4000);
wire select_slave1 = (master_paddr[31:16] == 16'h4001);
// VULNERABLE: No security attribute forwarding
// Cannot distinguish secure vs non-secure transactions
// All masters appear the same to slaves
always @(*) begin
// Forward to slave 0 (secure peripheral)
slave0_paddr = master_paddr;
slave0_pwdata = master_pwdata;
slave0_pwrite = master_pwrite;
slave0_psel = master_psel && select_slave0;
slave0_penable = master_penable;
// VULNERABLE: No protection signals to slave!
// Forward to slave 1
slave1_paddr = master_paddr;
slave1_pwdata = master_pwdata;
slave1_pwrite = master_pwrite;
slave1_psel = master_psel && select_slave1;
slave1_penable = master_penable;
end
// Attack:
// 1. Non-secure master accesses secure peripheral at 0x4000_xxxx
// 2. Bus has no way to indicate non-secure status
// 3. Secure peripheral cannot enforce access control
// 4. Non-secure world reads/writes secure data
endmodule
// Vulnerable: OCP fabric with unconfigured security signals
module vulnerable_ocp_master (
input wire clk,
input wire rst_n,
// Master signals
input wire [31:0] request_addr,
input wire [31:0] request_data,
input wire request_valid,
input wire request_write,
// OCP interface
output reg [31:0] MAddr,
output reg [31:0] MData,
output reg [2:0] MCmd,
// VULNERABLE: MReqInfo not connected!
// output reg [4:0] MReqInfo, // Security info - NOT USED
input wire SCmdAccept,
input wire [31:0] SData,
input wire [1:0] SResp
);
// OCP command encoding
localparam OCP_IDLE = 3'b000;
localparam OCP_WRITE = 3'b001;
localparam OCP_READ = 3'b010;
// VULNERABLE: Security information not included in transactions
// MReqInfo should carry privilege level and security state
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
MCmd <= OCP_IDLE;
end else if (request_valid) begin
MAddr <= request_addr;
MData <= request_data;
MCmd <= request_write ? OCP_WRITE : OCP_READ;
// VULNERABLE: MReqInfo never set
// Slave cannot determine transaction security level
end else begin
MCmd <= OCP_IDLE;
end
end
// Vulnerability: Even if slave checks MReqInfo,
// it will see default/undefined value
endmodule
// Vulnerable: Software using bus without security features
#include <stdint.h>
// VULNERABLE: Memory-mapped access without security context
void vulnerable_write_peripheral(uint32_t addr, uint32_t value) {
// Direct memory access
// No way to specify privilege level
// No way to indicate secure/non-secure
*(volatile uint32_t*)addr = value;
}
uint32_t vulnerable_read_peripheral(uint32_t addr) {
// VULNERABLE: Bus doesn't carry security attributes
// Peripheral cannot validate the access
return *(volatile uint32_t*)addr;
}
// Attack: Non-secure code can access secure peripherals
// because the bus doesn't support security separation
Fixed Code
// Fixed: APB interconnect with security signals
module secure_apb_interconnect (
input wire clk,
input wire rst_n,
// Master interface with security
input wire [31:0] master_paddr,
input wire [31:0] master_pwdata,
input wire master_pwrite,
input wire master_psel,
input wire master_penable,
input wire [2:0] master_pprot, // FIXED: Protection signals
// pprot[0] = privileged
// pprot[1] = non-secure
// pprot[2] = instruction/data
// Slave 0 - Secure peripheral
output reg [31:0] slave0_paddr,
output reg [31:0] slave0_pwdata,
output reg slave0_pwrite,
output reg slave0_psel,
output reg slave0_penable,
output reg [2:0] slave0_pprot, // FIXED: Forward protection
// Slave 1 - Normal peripheral
output reg [31:0] slave1_paddr,
output reg [31:0] slave1_pwdata,
output reg slave1_pwrite,
output reg slave1_psel,
output reg slave1_penable,
output reg [2:0] slave1_pprot,
// Access control
output reg access_denied
);
wire select_slave0 = (master_paddr[31:16] == 16'h4000);
wire select_slave1 = (master_paddr[31:16] == 16'h4001);
// FIXED: Secure slave access control
// Slave 0 requires secure (pprot[1] = 0) and privileged (pprot[0] = 1)
wire slave0_access_ok = (master_pprot[0] == 1'b1) && // Privileged
(master_pprot[1] == 1'b0); // Secure
always @(*) begin
access_denied = 1'b0;
// FIXED: Forward with security checks
slave0_paddr = master_paddr;
slave0_pwdata = master_pwdata;
slave0_pwrite = master_pwrite;
slave0_pprot = master_pprot; // FIXED: Forward protection signals
if (select_slave0) begin
// FIXED: Enforce access control at interconnect level
if (slave0_access_ok) begin
slave0_psel = master_psel;
slave0_penable = master_penable;
end else begin
// FIXED: Block non-secure or unprivileged access
slave0_psel = 1'b0;
slave0_penable = 1'b0;
access_denied = 1'b1;
end
end else begin
slave0_psel = 1'b0;
slave0_penable = 1'b0;
end
// Slave 1 - accessible to all
slave1_paddr = master_paddr;
slave1_pwdata = master_pwdata;
slave1_pwrite = master_pwrite;
slave1_psel = master_psel && select_slave1;
slave1_penable = master_penable;
slave1_pprot = master_pprot;
end
endmodule
// Fixed: OCP master with security signals configured
module secure_ocp_master (
input wire clk,
input wire rst_n,
// Master signals with security context
input wire [31:0] request_addr,
input wire [31:0] request_data,
input wire request_valid,
input wire request_write,
input wire [1:0] request_privilege, // 00=user, 01=priv, 10=secure, 11=secure-priv
input wire [2:0] request_master_id,
// OCP interface with security
output reg [31:0] MAddr,
output reg [31:0] MData,
output reg [2:0] MCmd,
output reg [4:0] MReqInfo, // FIXED: Security information
// MReqInfo[4:3] = privilege level
// MReqInfo[2:0] = master ID
input wire SCmdAccept,
input wire [31:0] SData,
input wire [1:0] SResp,
input wire [1:0] SRespInfo // FIXED: Response security info
);
localparam OCP_IDLE = 3'b000;
localparam OCP_WRITE = 3'b001;
localparam OCP_READ = 3'b010;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
MCmd <= OCP_IDLE;
MReqInfo <= 5'b00000;
end else if (request_valid) begin
MAddr <= request_addr;
MData <= request_data;
MCmd <= request_write ? OCP_WRITE : OCP_READ;
// FIXED: Include security information in transaction
MReqInfo[4:3] <= request_privilege;
MReqInfo[2:0] <= request_master_id;
end else begin
MCmd <= OCP_IDLE;
end
end
endmodule
// Fixed: AXI-based secure interconnect
module secure_axi_interconnect (
input wire clk,
input wire rst_n,
// Master interface
input wire [31:0] m_axi_awaddr,
input wire [2:0] m_axi_awprot, // FIXED: Write protection
input wire m_axi_awvalid,
input wire [31:0] m_axi_araddr,
input wire [2:0] m_axi_arprot, // FIXED: Read protection
input wire m_axi_arvalid,
// Slave interface
output reg [31:0] s_axi_awaddr,
output reg [2:0] s_axi_awprot,
output reg s_axi_awvalid,
output reg [31:0] s_axi_araddr,
output reg [2:0] s_axi_arprot,
output reg s_axi_arvalid,
output reg security_violation
);
// FIXED: AXI protection bit definitions
// AxPROT[0] = privileged (1) / unprivileged (0)
// AxPROT[1] = non-secure (1) / secure (0)
// AxPROT[2] = instruction (1) / data (0)
// FIXED: Define secure address ranges
localparam SECURE_BASE = 32'h1000_0000;
localparam SECURE_SIZE = 32'h0100_0000;
wire write_to_secure = (m_axi_awaddr >= SECURE_BASE) &&
(m_axi_awaddr < SECURE_BASE + SECURE_SIZE);
wire read_from_secure = (m_axi_araddr >= SECURE_BASE) &&
(m_axi_araddr < SECURE_BASE + SECURE_SIZE);
// FIXED: Check security attributes for secure region access
wire write_secure_ok = !m_axi_awprot[1]; // Secure access
wire read_secure_ok = !m_axi_arprot[1]; // Secure access
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
s_axi_awvalid <= 1'b0;
s_axi_arvalid <= 1'b0;
security_violation <= 1'b0;
end else begin
security_violation <= 1'b0;
// FIXED: Write channel with security check
if (m_axi_awvalid) begin
if (write_to_secure && !write_secure_ok) begin
// FIXED: Block non-secure access to secure region
s_axi_awvalid <= 1'b0;
security_violation <= 1'b1;
end else begin
s_axi_awaddr <= m_axi_awaddr;
s_axi_awprot <= m_axi_awprot;
s_axi_awvalid <= 1'b1;
end
end else begin
s_axi_awvalid <= 1'b0;
end
// FIXED: Read channel with security check
if (m_axi_arvalid) begin
if (read_from_secure && !read_secure_ok) begin
s_axi_arvalid <= 1'b0;
security_violation <= 1'b1;
end else begin
s_axi_araddr <= m_axi_araddr;
s_axi_arprot <= m_axi_arprot;
s_axi_arvalid <= 1'b1;
end
end else begin
s_axi_arvalid <= 1'b0;
end
end
end
endmodule
CVE Examples
- CVE-2020-8705: Platform fabric in Intel processors lacked proper security signal propagation.
- CVE-2019-0090: Intel CSME used buses without adequate security feature support.
Related CWEs
- CWE-693: Protection Mechanism Failure (parent)
- CWE-1198: Privilege Separation and Access Control Issues (category)
- CWE-1311: Improper Translation of Security Attributes by Fabric Bridge (related)
- CWE-1317: Improper Access Control in Fabric Bridge (related)
References
- MITRE Corporation. "CWE-1318: Missing Support for Security Features in On-chip Fabrics or Buses." https://cwe.mitre.org/data/definitions/1318.html
- ARM. "AMBA APB Protocol Specification"
- OCP-IP. "Open Core Protocol Specification"
- ARM. "AMBA AXI and ACE Protocol Specification"