The product uses a hardware module implementing a cryptographic
algorithm that writes sensitive information about the intermediate
state or results of its cryptographic operations via one of its output
wires (typically the output port containing the final result).

Primary

Implementation
This can occur when intermediate cryptographic states are
directly assigned to output wires or ports.

Confidentiality
Read Memory
Read Application Data
Unknown
Mathematically sound cryptographic algorithms rely on their
correct implementation for security. These assumptions might break when a
hardware crypto module leaks intermediate encryption states or results
such that they can be observed by an adversary. If intermediate state
is observed, it might be possible for an attacker to identify the
secrets used in the cryptographic operation.

Automated Static Analysis - Source Code
Automated static analysis can find some instances of this
weakness by analyzing source register-transfer level (RTL) code
without having to simulate it or analyze it with a formal verification
engine. Typically, this is done by building a model of data flow and
control flow, then searching for potentially-vulnerable patterns that
connect "sources" (signals with intermediate cryptographic
state/results) with "sinks" (hardware module outputs and other signals
outside of trusted cryptographic zone) without any control flow.
High
Static code analysis can sometimes lead to false positives.

Simulation / Emulation
Simulation/emulation based analysis can find some instances of
this weakness by simulating source register-transfer level (RTL) code
along with a set of assertions that incorporate the simulated values
of relevant design signals. Typically, these assertions will capture
desired or undesired behavior. Analysis can be improved by using
simulation-based information flow tracking (IFT) to more precisely
detect unexpected results.
High
Simulation/emulation based analysis can sometimes lead to false
negatives if the testbench does not drive the design to a design state
in which the assertion would fail.

Formal Verification
Formal verification can find some instances of this weakness by
exhaustively analyzing whether a given assertion holds true for a
given hardware design specified in register-transfer level (RTL)
code. Typically, these assertions will capture desired or undesired
behavior. For this weakness, an assertion should check for undesired
behavior in which one output is a signal that captures when a
cryptographic algorithm has completely finished; another output is a
signal with intermediate cryptographic state/results; and there is an
assignment to a hardware module output or other signal outside of a
trusted cryptographic zone.
Alternatively, when using a formal IFT verification, the same
undesired behavior can be detected by checking if computation results
can ever leak to an output when the cryptographic result is not
copmlete.

High
Formal verification may not scale for RTL designs with a large state space.

Manual Analysis
Manual analysis can find some instances of this weakness by
manually reviewing relevant lines of source register-transfer level
(RTL) code to detect potentially-vulnerable patterns. Typically, the
reviewer will trace the sequence of assignments that connect "sources"
(signals with intermediate cryptographic state/results) with "sinks"
(hardware module outputs and other signals outside of trusted
cryptographic zone). If this sequence of assignments is missing
adequate control flow, then the weakness is likely to exist.
Opportunistic
Manual analysis of source code is prone to errors (false
positives and false negatives) and highly opportunistic.

Architecture and Design
Designers/developers
should add or modify existing control flow
logic along any data flow paths that
connect "sources" (signals with
intermediate cryptographic state/results)
with "sinks" (hardware module outputs and
other signals outside of trusted
cryptographic zone). The control flow
logic should only allow cryptographic
results to be driven to "sinks" when
appropriate conditions are satisfied
(typically when the final result for a
cryptographic operation has been
generated). When the appropriate
conditions are not satisfied (i.e., before
or during a cryptographic operation), the
control flow logic should drive a safe
default value to
"sinks".
High

Implementation
Designers/developers
should add or modify existing control flow
logic along any data flow paths that
connect "sources" (signals with
intermediate cryptographic state/results)
with "sinks" (hardware module outputs and
other signals outside of trusted
cryptographic zone). The control flow
logic should only allow cryptographic
results to be driven to "sinks" when
appropriate conditions are satisfied
(typically when the final result for a
cryptographic operation has been
generated). When the appropriate
conditions are not satisfied (i.e., before
or during a cryptographic operation), the
control flow logic should drive a safe
default value to
"sinks".
High

The following SystemVerilog code is a crypto module that takes input
data and encrypts it by processing the data through multiple
encryption rounds. Note: this example is derived from [REF-1469].

01 | module crypto_core_with_leakage
02 | (

03 | input clk,
04 | input rst,
05 | input [127:0] data_i,
06 | output [127:0] data_o,
07 | output valid

08 | );
09 |
10 | localparam int total_rounds = 10;
11 | logic [3:0] round_id_q;
12 | logic [127:0] data_state_q, data_state_d;
13 | logic [127:0] key_state_q, key_state_d;
14 |
15 | crypto_algo_round u_algo_round (

16 | .clk (clk),
17 | .rst (rst),
18 | .round_i (round_id_q ),
19 | .key_i (key_state_q ),
20 | .data_i (data_state_q),
21 | .key_o (key_state_d ),
22 | .data_o (data_state_d)

23 | );
24 |
25 | always @(posedge clk) begin

26 | if (rst) begin

27 | data_state_q <= 0;
28 | key_state_q <= 0;
29 | round_id_q <= 0;

30 | end
31 | else begin

32 | case (round_id_q)

33 | total_rounds: begin

34 | data_state_q <= 0;
35 | key_state_q <= 0;
36 | round_id_q <= 0;

37 | end
38 |
39 | default: begin

40 | data_state_q <= data_state_d;
41 | key_state_q <= key_state_d;
42 | round_id_q <= round_id_q + 1;

43 | end

44 | endcase

45 | end

46 | end
47 |
48 | assign valid = (round_id_q == total_rounds) ? 1'b1 : 1'b0;
49 |
50 | assign data_o = data_state_q;
51 |
52 | endmodule

In line 50 above, data_state_q is assigned to data_o. Since data_state_q
contains intermediate state/results, this allows an attacker to obtain
these results through data_o.

In line 50 of the fixed logic below,
while "data_state_q" does not contain the final result,
a "sanitizing" mechanism drives a safe default value (i.e., 0) to
"data_o" instead of the value of "data_state_q".
In doing so, the mechanism prevents
the exposure of intermediate state/results which could be used to
break soundness of the cryptographic operation being performed. A
real-world example of this weakness and mitigation can be seen in a
pull request that was submitted to the OpenTitan Github repository
[REF-1469].

01 | module crypto_core_without_leakage
02 | (

03 | input clk,
04 | input rst,
05 | input [127:0] data_i,
06 | output [127:0] data_o,
07 | output valid
08 | );

09 |
10 | localparam int total_rounds = 10;
11 | logic [3:0] round_id_q;
12 | logic [127:0] data_state_q, data_state_d;
13 | logic [127:0] key_state_q, key_state_d;
14 |
15 | crypto_algo_round u_algo_round (

16 | .clk (clk),
17 | .rst (rst),
18 | .round_i (round_id_q ),
19 | .key_i (key_state_q ),
20 | .data_i (data_state_q),
21 | .key_o (key_state_d ),
22 | .data_o (data_state_d)

23 | );
24 |
25 | always @(posedge clk) begin

26 | if (rst) begin

27 | data_state_q <= 0;
28 | key_state_q <= 0;
29 | round_id_q <= 0;

30 | end
31 | else begin

32 | case (round_id_q)

33 | total_rounds: begin

34 | data_state_q <= 0;
35 | key_state_q <= 0;
36 | round_id_q <= 0;

37 | end
38 |
39 | default: begin

40 | data_state_q <= data_state_d;
41 | key_state_q <= key_state_d;
42 | round_id_q <= round_id_q + 1;

43 | end

44 | endcase

45 | end

46 | end
47 |
48 | assign valid = (round_id_q == total_rounds) ? 1'b1 : 1'b0;
49 |
50 | assign data_o = (valid) ? data_state_q : 0;
51 |
52 | endmodule

Allowed
This CWE entry is at the Base level of abstraction, which is a preferred level of abstraction for mapping to the root causes of vulnerabilities.
Carefully read both the name and description to ensure that this mapping is an appropriate fit. Do not try to 'force' a mapping to a lower-level Base/Variant simply to comply with this preferred level of abstraction.

Andres Meza
University of California, San Diego
2022-08-15
4.17
2025-04-03

CWE Content Team
MITRE
2025-09-09
4.18
2025-09-09
updated Relationships

CWE Content Team
MITRE
2025-12-11
4.19
2025-12-11
updated Weakness_Ordinalities