../src/lowrisc_ip_aes_0.6/rtl/aes_sbox_canright_masked_noreuse.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4: //
5: // AES Masked Canright SBox without Mask Re-Use
6: //
7: // For details, see the following paper:
8: // Canright, "A very compact 'perfectly masked' S-box for AES (corrected)"
9: // available at https://eprint.iacr.org/2009/011.pdf
10: //
11: // Note: This module implements the original masked inversion algorithm without re-using masks.
12: // For details, see Section 2.2 of the paper.
13:
14: ///////////////////////////////////////////////////////////////////////////////////////////////////
15: // IMPORTANT NOTE: //
16: // DO NOT USE THIS FOR SYNTHESIS BLINDLY! //
17: // //
18: // This is a high-level implementation targeting primarily RTL simulation. Synthesis tools might //
19: // heavily optimize the design. The result is likely insecure. Use with care. //
20: ///////////////////////////////////////////////////////////////////////////////////////////////////
21:
22: module aes_sbox_canright_masked_noreuse (
23: input aes_pkg::ciph_op_e op_i,
24: input logic [7:0] data_i, // masked, the actual input data is data_i ^ in_mask_i
25: input logic [7:0] in_mask_i, // input mask, independent from actual input data
26: input logic [7:0] out_mask_i, // output mask, independent from input mask
27: output logic [7:0] data_o // masked, the actual output data is data_o ^ out_mask_i
28: );
29:
30: import aes_pkg::*;
31: import aes_sbox_canright_pkg::*;
32:
33: ///////////////
34: // Functions //
35: ///////////////
36:
37: // Masked inverse in GF(2^4), using normal basis [z^4, z]
38: // (see Formulas 6, 13, 14, 15, 16, 17 in the paper)
39: function automatic logic [3:0] aes_masked_inverse_gf2p4(logic [3:0] b,
40: logic [3:0] q,
41: logic [1:0] r,
42: logic [3:0] t);
43: logic [3:0] b_inv;
44: logic [1:0] b1, b0, q1, q0, c, c_inv, r_sq, t1, t0, b1_inv, b0_inv;
45: b1 = b[3:2];
46: b0 = b[1:0];
47: q1 = q[3:2];
48: q0 = q[1:0];
49: t1 = t[3:2];
50: t0 = t[1:0];
51:
52: // Formula 13
53: // IMPORTANT: The following ops must be executed in order (left to right):
54: c = r ^ aes_scale_omega2_gf2p2(aes_square_gf2p2(b1 ^ b0))
55: ^ aes_scale_omega2_gf2p2(aes_square_gf2p2(q1 ^ q0))
56: ^ aes_mul_gf2p2(b1, b0)
57: ^ aes_mul_gf2p2(b1, q0) ^ aes_mul_gf2p2(b0, q1) ^ aes_mul_gf2p2(q1, q0);
58: //
59:
60: // Formulas 14 and 15
61: c_inv = aes_square_gf2p2(c);
62: r_sq = aes_square_gf2p2(r);
63:
64: // Formulas 16 and 17
65: // IMPORTANT: The following ops must be executed in order (left to right):
66: b1_inv = t1 ^ aes_mul_gf2p2(b0, c_inv)
67: ^ aes_mul_gf2p2(b0, r_sq) ^ aes_mul_gf2p2(q0, c_inv) ^ aes_mul_gf2p2(q0, r_sq);
68: b0_inv = t0 ^ aes_mul_gf2p2(b1, c_inv)
69: ^ aes_mul_gf2p2(b1, r_sq) ^ aes_mul_gf2p2(q1, c_inv) ^ aes_mul_gf2p2(q1, r_sq);
70: //
71:
72: // Note: b_inv is masked by t, b was masked by q.
73: b_inv = {b1_inv, b0_inv};
74:
75: return b_inv;
76: endfunction
77:
78: // Masked inverse in GF(2^8), using normal basis [y^16, y]
79: // (see Formulas 3, 12, 18 and 19 in the paper)
80: function automatic logic [7:0] aes_masked_inverse_gf2p8(logic [7:0] a,
81: logic [7:0] m,
82: logic [7:0] n);
83: logic [7:0] a_inv;
84: logic [3:0] a1, a0, m1, m0, b, b_inv, q, s1, s0, t, a1_inv, a0_inv;
85: logic [1:0] r;
86: a1 = a[7:4];
87: a0 = a[3:0];
88: m1 = m[7:4];
89: m0 = m[3:0];
90:
91: // q must be independent of m.
92: q = n[7:4];
93:
94: // Formula 12
95: // IMPORTANT: The following ops must be executed in order (left to right):
96: b = q ^ aes_square_scale_gf2p4_gf2p2(a1 ^ a0)
97: ^ aes_square_scale_gf2p4_gf2p2(m1 ^ m0)
98: ^ aes_mul_gf2p4(a1, a0)
99: ^ aes_mul_gf2p4(a1, m0) ^ aes_mul_gf2p4(a0, m1) ^ aes_mul_gf2p4(m1, m0);
100: //
101:
102: // r must be independent of q.
103: r = m1[3:2];
104:
105: // Note that the paper states the following requirements on t:
106: // - t must be independent of r.
107: // - t1 must be independent of q0, t0 must be independent of q1.
108: // - t must be independent of m (for the final steps involving s)
109: // The paper suggests to use t = q. To select s = n for the output mask (s must be independent
110: // of t = q = n[7:4]), we would need t = m0 or similar (not r, m1[3:2] though), but this would
111: // break the random product distribution of aes_mul_gf2p4(m0, t), or aes_mul_gf2p4(m1, t) below
112: // (see Lemma 2 in the paper). For this reason, we select t = q here and apply a final mask
113: // switch from s = m to n after the inversion.
114: t = q;
115:
116: // b is masked by q, b_inv is masked by t.
117: b_inv = aes_masked_inverse_gf2p4(b, q, r, t);
118:
119: // Note that the paper states the following requirements on s:
120: // - s must be independent of t
121: // - s1 must be independent of m0, s0 must be independent of m1.
122: // The paper suggests to use s = m (the input mask). To still end up with the specified output
123: // mask n, we will apply a final mask switch after the inversion.
124: s1 = m1;
125: s0 = m0;
126:
127: // Formulas 18 and 19
128: // IMPORTANT: The following ops must be executed in order (left to right):
129: a1_inv = s1 ^ aes_mul_gf2p4(a0, b_inv)
130: ^ aes_mul_gf2p4(a0, t) ^ aes_mul_gf2p4(m0, b_inv) ^ aes_mul_gf2p4(m0, t);
131: a0_inv = s0 ^ aes_mul_gf2p4(a1, b_inv)
132: ^ aes_mul_gf2p4(a1, t) ^ aes_mul_gf2p4(m1, b_inv) ^ aes_mul_gf2p4(m1, t);
133: //
134:
135: // Note: a_inv is now masked by s = m, a was masked by m.
136: a_inv = {a1_inv, a0_inv};
137:
138: // To have a_inv masked by n (the specified output mask), we perform a final mask switch.
139: // IMPORTANT: The following ops must be executed in order (left to right):
140: a_inv = a_inv ^ n ^ m;
141: //
142:
143: return a_inv;
144: endfunction
145:
146: //////////////////////////
147: // Masked Canright SBox //
148: //////////////////////////
149:
150: logic [7:0] data_basis_x, data_inverse;
151: logic [7:0] in_mask_basis_x;
152: logic [7:0] out_mask_basis_x;
153:
154: // Convert data to normal basis X.
155: assign data_basis_x = (op_i == CIPH_FWD) ? aes_mvm(data_i, A2X) :
156: aes_mvm(data_i ^ 8'h63, S2X);
157:
158: // Convert masks to normal basis X.
159: // The addition of constant 8'h63 following the affine transformation is skipped.
160: assign in_mask_basis_x = (op_i == CIPH_FWD) ? aes_mvm(in_mask_i, A2X) :
161: aes_mvm(in_mask_i, S2X);
162:
163: // The output mask is converted in the opposite direction.
164: assign out_mask_basis_x = (op_i == CIPH_INV) ? aes_mvm(out_mask_i, A2X) :
165: aes_mvm(out_mask_i, S2X);
166:
167: // Do the inversion in normal basis X.
168: assign data_inverse = aes_masked_inverse_gf2p8(data_basis_x, in_mask_basis_x, out_mask_basis_x);
169:
170: // Convert to basis S or A.
171: assign data_o = (op_i == CIPH_FWD) ? (aes_mvm(data_inverse, X2S) ^ 8'h63) :
172: (aes_mvm(data_inverse, X2A));
173:
174: endmodule
175: