Improper Isolation of Shared Resources in Network On Chip (NoC)
Description
Improper Isolation of Shared Resources in Network On Chip (NoC) occurs when the Network On Chip does not isolate or incorrectly isolates its on-chip-fabric and internal resources such that they are shared between trusted and untrusted agents, creating timing channels. Internal NoC resources including buffers, crossbars, switches, ports, and channels often experience resource contention when shared across trust domains. This interference enables attackers to infer data belonging to trusted agents through timing analysis while also degrading network throughput and latency.
Risk
Improper NoC isolation has severe implications. Timing side channels enabled. Trusted data inferable through contention. Denial of service through resource exhaustion. Network throughput degraded. Latency increased. Covert channels possible. Security boundaries violated. QoS guarantees broken. High likelihood when NoC resources are shared across trust domains without isolation.
Solution
Implement priority-based arbitration inside the NoC and have dedicated buffers or virtual channels for routing secret data from trusted agents during architecture and design phase. Separate physical or logical paths for different security domains. Use time-division multiplexing to prevent interference. Implement traffic shaping to reduce timing information leakage.
Common Consequences
| Impact | Details |
|---|---|
| Confidentiality | Scope: Confidentiality Attackers may extract sensitive data through timing channel analysis of shared NoC resources. |
| Availability | Scope: Availability Denial of service through resource consumption and network degradation. |
Example Code
Vulnerable Code
// Vulnerable: NoC router without isolation
module vulnerable_noc_router (
input wire clk,
input wire rst_n,
// Input ports (from different agents)
input wire [63:0] port_n_data,
input wire [7:0] port_n_dest,
input wire port_n_valid,
input wire port_n_secure, // Security attribute
input wire [63:0] port_s_data,
input wire [7:0] port_s_dest,
input wire port_s_valid,
input wire port_s_secure,
input wire [63:0] port_e_data,
input wire [7:0] port_e_dest,
input wire port_e_valid,
input wire port_e_secure,
input wire [63:0] port_w_data,
input wire [7:0] port_w_dest,
input wire port_w_valid,
input wire port_w_secure,
// Output ports
output reg [63:0] out_n_data,
output reg out_n_valid,
output reg [63:0] out_s_data,
output reg out_s_valid,
// ... other outputs
// Backpressure
output reg port_n_stall,
output reg port_s_stall,
output reg port_e_stall,
output reg port_w_stall
);
// VULNERABLE: Shared buffer for all traffic
reg [63:0] shared_buffer [0:15];
reg [3:0] buffer_head;
reg [3:0] buffer_tail;
reg [3:0] buffer_count;
// VULNERABLE: Single arbiter for all domains
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
buffer_count <= 4'b0;
end else begin
// VULNERABLE: All traffic competes for shared buffer
// Secure and non-secure traffic mixed
if (port_n_valid && buffer_count < 4'd15) begin
shared_buffer[buffer_tail] <= port_n_data;
buffer_tail <= buffer_tail + 1;
buffer_count <= buffer_count + 1;
end else if (port_s_valid && buffer_count < 4'd15) begin
shared_buffer[buffer_tail] <= port_s_data;
// ...
end
// VULNERABLE: No priority for secure traffic
// VULNERABLE: Timing visible through stall signals
end
end
// VULNERABLE: Shared crossbar
// Contention between secure and non-secure creates timing channel
always @(*) begin
// Round-robin arbitration doesn't consider security
// Attacker can observe when secure traffic is present
// by measuring their own traffic delays
end
// Attack:
// 1. Attacker sends traffic to measure baseline latency
// 2. Secure agent sends confidential data
// 3. Attacker observes increased latency (contention)
// 4. Timing channel reveals secure traffic patterns
endmodule
// Vulnerable: Virtual channel allocation without isolation
module vulnerable_vc_allocator (
input wire clk,
input wire rst_n,
input wire [3:0] vc_request,
input wire [3:0] vc_secure, // Which requests are secure
output reg [3:0] vc_grant,
output reg [1:0] vc_allocated
);
// VULNERABLE: All VCs shared across security domains
reg [3:0] vc_busy;
always @(posedge clk) begin
// VULNERABLE: No isolation of VCs by security level
// Secure traffic can be blocked by non-secure
if (vc_request[0] && !vc_busy[0]) begin
vc_grant <= 4'b0001;
vc_allocated <= 2'b00;
vc_busy[0] <= 1'b1;
end else if (vc_request[1] && !vc_busy[1]) begin
vc_grant <= 4'b0010;
// ...
end
// VULNERABLE: Non-secure can exhaust all VCs
// Creating DoS against secure traffic
end
endmodule
Fixed Code
// Fixed: NoC router with security isolation
module secure_noc_router (
input wire clk,
input wire rst_n,
// Input ports with security attributes
input wire [63:0] port_n_data,
input wire [7:0] port_n_dest,
input wire port_n_valid,
input wire port_n_secure,
input wire [63:0] port_s_data,
input wire [7:0] port_s_dest,
input wire port_s_valid,
input wire port_s_secure,
input wire [63:0] port_e_data,
input wire [7:0] port_e_dest,
input wire port_e_valid,
input wire port_e_secure,
input wire [63:0] port_w_data,
input wire [7:0] port_w_dest,
input wire port_w_valid,
input wire port_w_secure,
// Output ports
output reg [63:0] out_n_data,
output reg out_n_valid,
output reg [63:0] out_s_data,
output reg out_s_valid,
// Backpressure (isolated)
output reg port_n_stall,
output reg port_s_stall,
output reg port_e_stall,
output reg port_w_stall
);
// FIXED: Separate buffers for secure and non-secure traffic
reg [63:0] secure_buffer [0:7];
reg [2:0] secure_head, secure_tail;
reg [3:0] secure_count;
reg [63:0] nonsecure_buffer [0:7];
reg [2:0] nonsecure_head, nonsecure_tail;
reg [3:0] nonsecure_count;
// FIXED: Separate arbiters for each security domain
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
secure_count <= 4'b0;
nonsecure_count <= 4'b0;
end else begin
// FIXED: Route to appropriate buffer based on security
if (port_n_valid && port_n_secure && secure_count < 4'd7) begin
secure_buffer[secure_tail] <= port_n_data;
secure_tail <= secure_tail + 1;
secure_count <= secure_count + 1;
end else if (port_n_valid && !port_n_secure && nonsecure_count < 4'd7) begin
nonsecure_buffer[nonsecure_tail] <= port_n_data;
nonsecure_tail <= nonsecure_tail + 1;
nonsecure_count <= nonsecure_count + 1;
end
// Similar for other ports...
end
end
// FIXED: Priority-based arbitration favoring secure traffic
reg secure_has_priority;
always @(posedge clk) begin
// FIXED: Secure traffic gets priority access to output
if (secure_count > 0) begin
out_n_data <= secure_buffer[secure_head];
out_n_valid <= 1'b1;
secure_head <= secure_head + 1;
secure_count <= secure_count - 1;
end else if (nonsecure_count > 0) begin
out_n_data <= nonsecure_buffer[nonsecure_head];
out_n_valid <= 1'b1;
nonsecure_head <= nonsecure_head + 1;
nonsecure_count <= nonsecure_count - 1;
end else begin
out_n_valid <= 1'b0;
end
end
// FIXED: Isolated stall signals
// Non-secure backpressure doesn't reveal secure traffic state
always @(*) begin
port_n_stall = (port_n_secure ? (secure_count >= 4'd7) :
(nonsecure_count >= 4'd7));
// ...
end
endmodule
// Fixed: Time-division multiplexed NoC for strong isolation
module secure_tdm_noc_router (
input wire clk,
input wire rst_n,
// Time slot configuration
input wire [3:0] current_slot,
input wire [3:0] secure_slots, // Bitmap of slots for secure traffic
// Ports
input wire [63:0] in_data,
input wire in_valid,
input wire in_secure,
output reg [63:0] out_data,
output reg out_valid
);
// FIXED: Time-division multiplexing for isolation
wire slot_is_secure = secure_slots[current_slot];
always @(posedge clk) begin
// FIXED: Only route traffic matching current slot type
if (in_valid && (in_secure == slot_is_secure)) begin
out_data <= in_data;
out_valid <= 1'b1;
end else begin
// FIXED: Padding traffic to prevent timing analysis
out_data <= 64'h0;
out_valid <= slot_is_secure ? 1'b0 : 1'b0;
end
end
// FIXED: TDM ensures no interference between domains
// Timing is deterministic regardless of traffic patterns
endmodule
// Fixed: Virtual channel allocator with security isolation
module secure_vc_allocator (
input wire clk,
input wire rst_n,
input wire [3:0] vc_request,
input wire [3:0] vc_secure,
output reg [3:0] vc_grant,
output reg [1:0] vc_allocated
);
// FIXED: Dedicated VCs for each security domain
// VCs 0-1: Secure traffic only
// VCs 2-3: Non-secure traffic only
reg [1:0] secure_vc_busy;
reg [1:0] nonsecure_vc_busy;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
secure_vc_busy <= 2'b0;
nonsecure_vc_busy <= 2'b0;
vc_grant <= 4'b0;
end else begin
vc_grant <= 4'b0;
// FIXED: Allocate from appropriate pool
for (int i = 0; i < 4; i++) begin
if (vc_request[i]) begin
if (vc_secure[i]) begin
// FIXED: Secure requests get secure VCs
if (!secure_vc_busy[0]) begin
vc_grant[i] <= 1'b1;
vc_allocated <= 2'b00;
secure_vc_busy[0] <= 1'b1;
end else if (!secure_vc_busy[1]) begin
vc_grant[i] <= 1'b1;
vc_allocated <= 2'b01;
secure_vc_busy[1] <= 1'b1;
end
// FIXED: Non-secure cannot exhaust secure VCs
end else begin
// FIXED: Non-secure requests get non-secure VCs
if (!nonsecure_vc_busy[0]) begin
vc_grant[i] <= 1'b1;
vc_allocated <= 2'b10;
nonsecure_vc_busy[0] <= 1'b1;
end else if (!nonsecure_vc_busy[1]) begin
vc_grant[i] <= 1'b1;
vc_allocated <= 2'b11;
nonsecure_vc_busy[1] <= 1'b1;
end
end
end
end
end
end
endmodule
CVE Examples
- CVE-2021-33096: Improper isolation of shared NoC resources causing denial of service.
- CVE-2020-0551: Load value injection through NoC timing channels.
Related CWEs
- CWE-653: Improper Isolation or Compartmentalization (parent)
- CWE-668: Exposure of Resource to Wrong Sphere (parent)
- CWE-1189: Improper Isolation of Shared Resources on System-on-a-Chip (SoC) (peer)
- CWE-1203: Peripherals, On-chip Fabric, and Interface/IO Problems (category)
References
- MITRE Corporation. "CWE-1331: Improper Isolation of Shared Resources in Network On Chip (NoC)." https://cwe.mitre.org/data/definitions/1331.html
- ACM. "NoC Security Survey: Attacks, Countermeasures, and Evaluation"
- IEEE. "Secure Network-on-Chip Architectures"