1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2018-2021, 2023 NXP
4 *
5 * CAAM Prime Numbering.
6 * Implementation of Prime Number functions
7 */
8 #include <caam_common.h>
9 #include <caam_desc_ccb_defines.h>
10 #include <caam_jr.h>
11 #include <caam_utils_mem.h>
12 #include <kernel/panic.h>
13 #include <mm/core_memprot.h>
14 #include <string.h>
15 #include <tee_api_types.h>
16 #include <tee/cache.h>
17
18 #include "local.h"
19
20 #define RSA_TRY_FAIL 0x42
21 #define RETRY_TOO_SMALL 0x2A
22
23 #define STATUS_GOOD_Q 0xCA
24
25 #define MR_PRIME_SIZE 1536
26 #define MAX_RETRY_PRIME_GEN 1000
27 #define RSA_MAX_TRIES_PRIMES 100
28
29 #ifdef CFG_CAAM_64BIT
30 #define SETUP_RSA_DESC_ENTRIES 20
31 #define GEN_RSA_DESC_ENTRIES 62
32 #define CHECK_P_Q_DESC_ENTRIES 32
33 #else
34 #define SETUP_RSA_DESC_ENTRIES 17
35 #define GEN_RSA_DESC_ENTRIES 58
36 #define CHECK_P_Q_DESC_ENTRIES 29
37 #endif
38
39 /*
40 * Predefined const value corresponding to the
41 * operation sqrt(2) * (2 ^ ((nlen / 2) - 1))
42 * Used at step 4.4
43 */
44 static const uint8_t sqrt_value[] = {
45 0xb5, 0x04, 0xf3, 0x33, 0xf9, 0xde, 0x64, 0x84, 0x59, 0x7d, 0x89, 0xb3,
46 0x75, 0x4a, 0xbe, 0x9f, 0x1d, 0x6f, 0x60, 0xba, 0x89, 0x3b, 0xa8, 0x4c,
47 0xed, 0x17, 0xac, 0x85, 0x83, 0x33, 0x99, 0x15, 0x4a, 0xfc, 0x83, 0x04,
48 0x3a, 0xb8, 0xa2, 0xc3, 0xa8, 0xb1, 0xfe, 0x6f, 0xdc, 0x83, 0xdb, 0x39,
49 0x0f, 0x74, 0xa8, 0x5e, 0x43, 0x9c, 0x7b, 0x4a, 0x78, 0x04, 0x87, 0x36,
50 0x3d, 0xfa, 0x27, 0x68, 0xd2, 0x20, 0x2e, 0x87, 0x42, 0xaf, 0x1f, 0x4e,
51 0x53, 0x05, 0x9c, 0x60, 0x11, 0xbc, 0x33, 0x7b, 0xca, 0xb1, 0xbc, 0x91,
52 0x16, 0x88, 0x45, 0x8a, 0x46, 0x0a, 0xbc, 0x72, 0x2f, 0x7c, 0x4e, 0x33,
53 0xc6, 0xd5, 0xa8, 0xa3, 0x8b, 0xb7, 0xe9, 0xdc, 0xcb, 0x2a, 0x63, 0x43,
54 0x31, 0xf3, 0xc8, 0x4d, 0xf5, 0x2f, 0x12, 0x0f, 0x83, 0x6e, 0x58, 0x2e,
55 0xea, 0xa4, 0xa0, 0x89, 0x90, 0x40, 0xca, 0x4a, 0x81, 0x39, 0x4a, 0xb6,
56 0xd8, 0xfd, 0x0e, 0xfd, 0xf4, 0xd3, 0xa0, 0x2c, 0xeb, 0xc9, 0x3e, 0x0c,
57 0x42, 0x64, 0xda, 0xbc, 0xd5, 0x28, 0xb6, 0x51, 0xb8, 0xcf, 0x34, 0x1b,
58 0x6f, 0x82, 0x36, 0xc7, 0x01, 0x04, 0xdc, 0x01, 0xfe, 0x32, 0x35, 0x2f,
59 0x33, 0x2a, 0x5e, 0x9f, 0x7b, 0xda, 0x1e, 0xbf, 0xf6, 0xa1, 0xbe, 0x3f,
60 0xca, 0x22, 0x13, 0x07, 0xde, 0xa0, 0x62, 0x41, 0xf7, 0xaa, 0x81, 0xc2,
61 0xc1, 0xfc, 0xbd, 0xde, 0xa2, 0xf7, 0xdc, 0x33, 0x18, 0x83, 0x8a, 0x2e,
62 0xaf, 0xf5, 0xf3, 0xb2, 0xd2, 0x4f, 0x4a, 0x76, 0x3f, 0xac, 0xb8, 0x82,
63 0xfd, 0xfe, 0x17, 0x0f, 0xd3, 0xb1, 0xf7, 0x80, 0xf9, 0xac, 0xce, 0x41,
64 0x79, 0x7f, 0x28, 0x05, 0xc2, 0x46, 0x78, 0x5e, 0x92, 0x95, 0x70, 0x23,
65 0x5f, 0xcf, 0x8f, 0x7b, 0xca, 0x3e, 0xa3, 0x3b, 0x4d, 0x7c, 0x60, 0xa5,
66 0xe6, 0x33, 0xe3, 0xe1
67 };
68
69 /*
70 * Speedups for prime searching
71 *
72 * These values are products of small primes. Information about the product
73 * preceeds it. These values have been pre-computed by the CAAM design team.
74 *
75 * Per Handbook of Applied Cryptography, Menezes et al, 4.4.1, one can compute
76 * the percentage of non-primes weeded out by checking for small prime factors
77 * in the candidates. In the table below, "highest prime" is used for B, and
78 * "%weeded" is the number of candidates which get through this
79 * sieve. As you can see, even with relatively few primes, there are
80 * diminishing returns to using larger numbers of primes.
81 *
82 * Percentage weeded: 1 - 1.12/ln B
83 *
84 * These can be used to compute GCD(prime, smallprime) before the Miller
85 * Rabin; this will weed out those candidates with 'small' primes before doing
86 * the costly modular exponentation inside of Miller-Rabin. (If the result is
87 * not one, then the candidate has as a factor at least one of the small primes
88 * in the product).
89 *
90 * So, where is the sweet spot for the size of the product versus the size of
91 * the candidate? Does it depend upon the size of the PKHA multiplier? Hunt
92 * time for primes takes a long time to actually compute, and what are the
93 * stats for percentage of candidates that might be weeded out? If not many,
94 * then there is an extra computation.
95 */
96 struct smallprime {
97 const size_t length;
98 const uint8_t *data;
99 };
100
101 /* sizes | #primes | highest prime | %weeded */
102 /* bits / bytes | | */
103 /* 64 / 8 | 15 | 53 | 72 */
104 static const uint8_t smallprime_8[] = {
105 0xe2, 0x21, 0xf9, 0x7c, 0x30, 0xe9, 0x4e, 0x1d,
106 };
107
108 /* 128 / 16 | 25 | 101 | 76 */
109 static const uint8_t smallprime_16[] = {
110 0x57, 0x97, 0xd4, 0x7c, 0x51, 0x68, 0x15, 0x49, 0xd7, 0x34, 0xe4, 0xfc,
111 0x4c, 0x3e, 0xaf, 0x7f,
112 };
113
114 /* 256 / 32 | 43 | 193 | 79 */
115 static const uint8_t smallprime_32[] = {
116 0xdb, 0xf0, 0x5b, 0x6f, 0x56, 0x54, 0xb3, 0xc0, 0xf5, 0x24, 0x35, 0x51,
117 0x43, 0x95, 0x86, 0x88, 0x9f, 0x15, 0x58, 0x87, 0x81, 0x9a, 0xed, 0x2a,
118 0xc0, 0x5b, 0x93, 0x35, 0x2b, 0xe9, 0x86, 0x77,
119 };
120
121 /* 384 / 48 | 59 | 281 | 80 */
122 static const uint8_t smallprime_48[] = {
123 0x50, 0x12, 0x01, 0xcc, 0x51, 0xa4, 0x92, 0xa5, 0x44, 0xd3, 0x90, 0x0a,
124 0xd4, 0xf8, 0xb3, 0x2a, 0x20, 0x3c, 0x85, 0x84, 0x06, 0xa4, 0x45, 0x7c,
125 0xab, 0x0b, 0x4f, 0x80, 0x5a, 0xb1, 0x8a, 0xc6, 0xeb, 0x95, 0x72, 0xac,
126 0x6e, 0x93, 0x94, 0xfa, 0x52, 0x2b, 0xff, 0xb6, 0xf4, 0x4a, 0xf2, 0xf3,
127 };
128
129 /* 512 / 64 | 74 | 379 | 81 */
130 static const uint8_t smallprime_64[] = {
131 0x10, 0x6a, 0xa9, 0xfb, 0x76, 0x46, 0xfa, 0x6e, 0xb0, 0x81, 0x3c, 0x28,
132 0xc5, 0xd5, 0xf0, 0x9f, 0x07, 0x7e, 0xc3, 0xba, 0x23, 0x8b, 0xfb, 0x99,
133 0xc1, 0xb6, 0x31, 0xa2, 0x03, 0xe8, 0x11, 0x87, 0x23, 0x3d, 0xb1, 0x17,
134 0xcb, 0xc3, 0x84, 0x05, 0x6e, 0xf0, 0x46, 0x59, 0xa4, 0xa1, 0x1d, 0xe4,
135 0x9f, 0x7e, 0xcb, 0x29, 0xba, 0xda, 0x8f, 0x98, 0x0d, 0xec, 0xec, 0xe9,
136 0x2e, 0x30, 0xc4, 0x8f,
137 };
138
139 /* 576 / 72 | 81 | 421 | 82 */
140 static const uint8_t smallprime_72[] = {
141 0x01, 0x85, 0xdb, 0xeb, 0x2b, 0x8b, 0x11, 0xd3, 0x76, 0x33, 0xe9, 0xdc,
142 0x1e, 0xec, 0x54, 0x15, 0x65, 0xc6, 0xce, 0x84, 0x31, 0xd2, 0x27, 0xee,
143 0x28, 0xf0, 0x32, 0x8a, 0x60, 0xc9, 0x01, 0x18, 0xae, 0x03, 0x1c, 0xc5,
144 0xa7, 0x81, 0xc8, 0x24, 0xd1, 0xf1, 0x6d, 0x25, 0xf4, 0xf0, 0xcc, 0xcf,
145 0xf3, 0x5e, 0x97, 0x45, 0x79, 0x07, 0x2e, 0xc8, 0xca, 0xf1, 0xac, 0x8e,
146 0xef, 0xd5, 0x56, 0x6f, 0xa1, 0x5f, 0xb9, 0x4f, 0xe3, 0x4f, 0x5d, 0x37,
147 };
148
149 /* 768 / 96 | 103 | 569 | 82 */
150 static const uint8_t smallprime_96[] = {
151 0x25, 0xea, 0xc8, 0x9f, 0x8d, 0x4d, 0xa3, 0x38, 0x33, 0x7b, 0x49, 0x85,
152 0x0d, 0x2d, 0x14, 0x89, 0x26, 0x63, 0x17, 0x7b, 0x40, 0x10, 0xaf, 0x3d,
153 0xd2, 0x3e, 0xeb, 0x0b, 0x22, 0x8f, 0x38, 0x32, 0xff, 0xce, 0xe2, 0xe5,
154 0xcb, 0xd1, 0xac, 0xc9, 0x8f, 0x47, 0xf2, 0x51, 0x87, 0x33, 0x80, 0xae,
155 0x10, 0xf0, 0xff, 0xdd, 0x8e, 0x60, 0x2f, 0xfa, 0x21, 0x0f, 0x41, 0xf6,
156 0x69, 0xa1, 0x57, 0x0a, 0x93, 0xc1, 0x58, 0xc1, 0xa9, 0xa8, 0x22, 0x7f,
157 0xf8, 0x1a, 0x90, 0xc5, 0x63, 0x0e, 0x9c, 0x44, 0x84, 0x5c, 0x75, 0x5c,
158 0x7d, 0xf3, 0x5a, 0x7d, 0x43, 0x0c, 0x67, 0x9a, 0x11, 0x57, 0x56, 0x55,
159 };
160
161 /* 1024 / 128 | 130 | 739 | 83 */
162 static const uint8_t smallprime_128[] = {
163 0x02, 0xc8, 0x5f, 0xf8, 0x70, 0xf2, 0x4b, 0xe8, 0x0f, 0x62, 0xb1, 0xba,
164 0x6c, 0x20, 0xbd, 0x72, 0xb8, 0x37, 0xef, 0xdf, 0x12, 0x12, 0x06, 0xd8,
165 0x7d, 0xb5, 0x6b, 0x7d, 0x69, 0xfa, 0x4c, 0x02, 0x1c, 0x10, 0x7c, 0x3c,
166 0xa2, 0x06, 0xfe, 0x8f, 0xa7, 0x08, 0x0e, 0xf5, 0x76, 0xef, 0xfc, 0x82,
167 0xf9, 0xb1, 0x0f, 0x57, 0x50, 0x65, 0x6b, 0x77, 0x94, 0xb1, 0x6a, 0xfd,
168 0x70, 0x99, 0x6e, 0x91, 0xae, 0xf6, 0xe0, 0xad, 0x15, 0xe9, 0x1b, 0x07,
169 0x1a, 0xc9, 0xb2, 0x4d, 0x98, 0xb2, 0x33, 0xad, 0x86, 0xee, 0x05, 0x55,
170 0x18, 0xe5, 0x8e, 0x56, 0x63, 0x8e, 0xf1, 0x8b, 0xac, 0x5c, 0x74, 0xcb,
171 0x35, 0xbb, 0xb6, 0xe5, 0xda, 0xe2, 0x78, 0x3d, 0xd1, 0xc0, 0xce, 0x7d,
172 0xec, 0x4f, 0xc7, 0x0e, 0x51, 0x86, 0xd4, 0x11, 0xdf, 0x36, 0x36, 0x8f,
173 0x06, 0x1a, 0xa3, 0x60, 0x11, 0xf3, 0x01, 0x79,
174 };
175
176 /* 1088 / 184 | 136 | 787 | 83 */
177 static const uint8_t smallprime_184[] = {
178 0x16, 0xaf, 0x5c, 0x18, 0xa2, 0xbe, 0xf8, 0xef, 0xf2, 0x27, 0x83, 0x32,
179 0x18, 0x2d, 0x0f, 0xbf, 0x00, 0x38, 0xcc, 0x20, 0x51, 0x48, 0xb8, 0x3d,
180 0x06, 0xe3, 0xd7, 0xd9, 0x32, 0x82, 0x8b, 0x18, 0xe1, 0x1e, 0x09, 0x40,
181 0x28, 0xc7, 0xea, 0xed, 0xa3, 0x39, 0x50, 0x17, 0xe0, 0x7d, 0x8a, 0xe9,
182 0xb5, 0x94, 0x06, 0x04, 0x51, 0xd0, 0x5f, 0x93, 0x08, 0x4c, 0xb4, 0x81,
183 0x66, 0x3c, 0x94, 0xc6, 0xff, 0x98, 0x0d, 0xde, 0xcc, 0xdb, 0x42, 0xad,
184 0x37, 0x09, 0x7f, 0x41, 0xa7, 0x83, 0x7f, 0xc9, 0x5a, 0xfe, 0x3f, 0x18,
185 0xad, 0x76, 0xf2, 0x34, 0x83, 0xae, 0x94, 0x2e, 0x0f, 0x0c, 0x0b, 0xc6,
186 0xe4, 0x00, 0x16, 0x12, 0x31, 0x89, 0x87, 0x2b, 0xe5, 0x8f, 0x6d, 0xfc,
187 0x23, 0x9c, 0xa2, 0x8f, 0xb0, 0xcf, 0xbf, 0x96, 0x4c, 0x8f, 0x27, 0xce,
188 0x05, 0xd6, 0xc7, 0x7a, 0x01, 0xf9, 0xd3, 0x32, 0x36, 0xc9, 0xd4, 0x42,
189 0xad, 0x69, 0xed, 0x33,
190 };
191
192 /* 1536 / 192 | 182 | 1093 | 84 */
193 static const uint8_t smallprime_192[] = {
194 0x02, 0x1b, 0xf9, 0x49, 0x70, 0x91, 0xb8, 0xc3, 0x68, 0xcc, 0x7c, 0x8e,
195 0x00, 0xc1, 0x99, 0x0c, 0x60, 0x27, 0x48, 0x1b, 0x79, 0x21, 0x5a, 0xc8,
196 0xa7, 0x51, 0x77, 0x49, 0xa2, 0x15, 0x13, 0x77, 0x9a, 0x99, 0x3d, 0x29,
197 0x58, 0xfc, 0xb4, 0x9a, 0x73, 0x68, 0x02, 0x92, 0x68, 0x52, 0x79, 0x94,
198 0xc6, 0xcc, 0x19, 0x28, 0xad, 0xd4, 0x12, 0x95, 0x96, 0x76, 0x5f, 0x4c,
199 0xc3, 0x14, 0x1a, 0x04, 0x4e, 0xb1, 0xd6, 0x15, 0x78, 0x88, 0x16, 0x67,
200 0x57, 0xd8, 0x61, 0x87, 0x81, 0x81, 0x30, 0x62, 0x03, 0x22, 0x67, 0x98,
201 0x7d, 0xf0, 0xd4, 0x71, 0x9c, 0xd3, 0x8f, 0x1b, 0x70, 0x85, 0xfc, 0xa5,
202 0x33, 0x4b, 0xe3, 0xa6, 0x00, 0x3a, 0x3c, 0xe7, 0xe1, 0x9a, 0xba, 0x55,
203 0x3e, 0x80, 0xcc, 0x5a, 0xe4, 0x06, 0x0e, 0xff, 0x6e, 0x18, 0x06, 0x66,
204 0x1d, 0xa5, 0xee, 0xb7, 0xd1, 0x42, 0xd3, 0xb2, 0xe4, 0x07, 0x39, 0xf1,
205 0x44, 0x3d, 0xee, 0x3a, 0x19, 0x86, 0x37, 0xf0, 0x3c, 0x06, 0x28, 0x45,
206 0xea, 0xff, 0x3f, 0xf2, 0x7e, 0xa3, 0x8d, 0x93, 0x44, 0xd8, 0xa9, 0x02,
207 0x22, 0x47, 0x2d, 0xf0, 0x7d, 0xfb, 0x5c, 0x9c, 0x8a, 0xda, 0x77, 0xcd,
208 0x0d, 0x5b, 0x94, 0xef, 0xf0, 0x21, 0xe0, 0x2e, 0x30, 0x7d, 0x08, 0x01,
209 0x03, 0x12, 0xd5, 0x7c, 0xb5, 0xd9, 0x75, 0x76, 0x46, 0x97, 0x84, 0x2d,
210 };
211
212 /* 2048 / 256 | 232 | 1471 | 85 */
213 static const uint8_t smallprime_256[] = {
214 0x24, 0x65, 0xa7, 0xbd, 0x85, 0x01, 0x1e, 0x1c, 0x9e, 0x05, 0x27, 0x92,
215 0x9f, 0xff, 0x26, 0x8c, 0x82, 0xef, 0x7e, 0xfa, 0x41, 0x68, 0x63, 0xba,
216 0xa5, 0xac, 0xdb, 0x09, 0x71, 0xdb, 0xa0, 0xcc, 0xac, 0x3e, 0xe4, 0x99,
217 0x93, 0x45, 0x02, 0x9f, 0x2c, 0xf8, 0x10, 0xb9, 0x9e, 0x40, 0x6a, 0xac,
218 0x5f, 0xce, 0x5d, 0xd6, 0x9d, 0x1c, 0x71, 0x7d, 0xae, 0xa5, 0xd1, 0x8a,
219 0xb9, 0x13, 0xf4, 0x56, 0x50, 0x56, 0x79, 0xbc, 0x91, 0xc5, 0x7d, 0x46,
220 0xd9, 0x88, 0x88, 0x57, 0x86, 0x2b, 0x36, 0xe2, 0xed, 0xe2, 0xe4, 0x73,
221 0xc1, 0xf0, 0xab, 0x35, 0x9d, 0xa2, 0x52, 0x71, 0xaf, 0xfe, 0x15, 0xff,
222 0x24, 0x0e, 0x29, 0x9d, 0x0b, 0x04, 0xf4, 0xcd, 0x0e, 0x4d, 0x7c, 0x0e,
223 0x47, 0xb1, 0xa7, 0xba, 0x00, 0x7d, 0xe8, 0x9a, 0xae, 0x84, 0x8f, 0xd5,
224 0xbd, 0xcd, 0x7f, 0x98, 0x15, 0x56, 0x4e, 0xb0, 0x60, 0xae, 0x14, 0xf1,
225 0x9c, 0xb5, 0x0c, 0x29, 0x1f, 0x0b, 0xbd, 0x8e, 0xd1, 0xc4, 0xc7, 0xf8,
226 0xfc, 0x5f, 0xba, 0x51, 0x66, 0x20, 0x01, 0x93, 0x9b, 0x53, 0x2d, 0x92,
227 0xda, 0xc8, 0x44, 0xa8, 0x43, 0x1d, 0x40, 0x0c, 0x83, 0x2d, 0x03, 0x9f,
228 0x5f, 0x90, 0x0b, 0x27, 0x8a, 0x75, 0x21, 0x9c, 0x29, 0x86, 0x14, 0x0c,
229 0x79, 0x04, 0x5d, 0x77, 0x59, 0x54, 0x08, 0x54, 0xc3, 0x15, 0x04, 0xdc,
230 0x56, 0xf1, 0xdf, 0x5e, 0xeb, 0xe7, 0xbe, 0xe4, 0x47, 0x65, 0x8b, 0x91,
231 0x7b, 0xf6, 0x96, 0xd6, 0x92, 0x7f, 0x2e, 0x24, 0x28, 0xfb, 0xeb, 0x34,
232 0x0e, 0x51, 0x5c, 0xb9, 0x83, 0x5d, 0x63, 0x87, 0x1b, 0xe8, 0xbb, 0xe0,
233 0x9c, 0xf1, 0x34, 0x45, 0x79, 0x9f, 0x2e, 0x67, 0x78, 0x81, 0x51, 0x57,
234 0x1a, 0x93, 0xb4, 0xc1, 0xee, 0xe5, 0x5d, 0x1b, 0x90, 0x72, 0xe0, 0xb2,
235 0xf5, 0xc4, 0x60, 0x7f,
236 };
237
238 /* 3072 / 384 | 326 | 2179 | 85 */
239 static const uint8_t smallprime_384[] = {
240 0x00, 0x4d, 0xc2, 0x0e, 0x27, 0x31, 0x51, 0x23, 0xfd, 0xab, 0xcd, 0x18,
241 0xca, 0x81, 0x2e, 0xe0, 0xee, 0x44, 0x49, 0x23, 0x87, 0x38, 0x9e, 0xd6,
242 0xc9, 0x16, 0x97, 0x95, 0x89, 0x65, 0xed, 0xc5, 0x3d, 0x89, 0x13, 0xa8,
243 0xe6, 0xec, 0x7f, 0x83, 0x6a, 0x8b, 0xd6, 0x03, 0x7e, 0x57, 0xed, 0x0c,
244 0x69, 0x30, 0xef, 0x26, 0x49, 0x0d, 0xc3, 0x5d, 0x05, 0xd0, 0x98, 0xa4,
245 0x66, 0xad, 0xf8, 0x17, 0x9f, 0x82, 0x99, 0x69, 0xd1, 0x39, 0x55, 0x8f,
246 0x16, 0xe9, 0x8b, 0x3f, 0x76, 0xfc, 0x90, 0x62, 0xc1, 0x57, 0x25, 0xce,
247 0x09, 0x88, 0xfa, 0xed, 0xca, 0x96, 0x6a, 0x6b, 0x92, 0x5f, 0x9b, 0x9c,
248 0x67, 0x03, 0x43, 0xea, 0x7e, 0x84, 0x20, 0x65, 0xbd, 0x26, 0xf2, 0xbf,
249 0x29, 0x90, 0x4f, 0xa7, 0xf4, 0x9f, 0x33, 0x49, 0x28, 0x96, 0x33, 0x73,
250 0xba, 0x08, 0x95, 0x96, 0x51, 0x3d, 0xac, 0xa7, 0x39, 0x28, 0xcf, 0x30,
251 0x5a, 0xdf, 0x8c, 0x24, 0x6e, 0x1d, 0x99, 0xa2, 0x42, 0xd9, 0x23, 0x56,
252 0x23, 0xc4, 0x9a, 0xf2, 0x91, 0x45, 0x06, 0xc9, 0x11, 0x21, 0x5e, 0x1e,
253 0x49, 0xaf, 0x84, 0x80, 0x3e, 0xd9, 0xa2, 0xca, 0x05, 0x51, 0x72, 0x1f,
254 0xe6, 0x31, 0x9b, 0xf2, 0x38, 0xc0, 0x8a, 0xae, 0x6f, 0xd5, 0x01, 0x54,
255 0x03, 0xd9, 0xe5, 0x55, 0x09, 0xee, 0x31, 0xc9, 0x60, 0x12, 0xf9, 0x08,
256 0x35, 0x18, 0x5f, 0x31, 0xcb, 0xd2, 0xe4, 0x89, 0x83, 0x3c, 0x1d, 0x54,
257 0x62, 0xfa, 0x80, 0x53, 0x59, 0x04, 0x86, 0x7b, 0x2c, 0x94, 0x5e, 0x9a,
258 0x0c, 0x2f, 0x7a, 0xa3, 0x6e, 0x0a, 0xc0, 0xeb, 0x9b, 0xb4, 0xc1, 0x1b,
259 0xf5, 0x80, 0xcf, 0x0d, 0x6d, 0x2a, 0x49, 0xed, 0x1a, 0x2d, 0x74, 0xca,
260 0xe0, 0xf4, 0xc3, 0xad, 0xff, 0x61, 0xd6, 0x48, 0xca, 0x6a, 0x12, 0x08,
261 0x58, 0xf4, 0xab, 0xb3, 0xb3, 0x12, 0x07, 0xcf, 0x9b, 0x7c, 0x2f, 0xda,
262 0x74, 0xf7, 0x72, 0x2b, 0x14, 0x99, 0x17, 0x87, 0x5a, 0xac, 0x9d, 0x61,
263 0x53, 0xc9, 0x71, 0x13, 0xfc, 0xd3, 0x74, 0xaf, 0x93, 0xdd, 0x3f, 0xa2,
264 0x1a, 0x7d, 0xe5, 0x1f, 0x1a, 0x70, 0xc6, 0x31, 0xba, 0x6c, 0x92, 0x26,
265 0x1e, 0x89, 0x54, 0x1a, 0xa4, 0x71, 0x41, 0xf4, 0x4e, 0x07, 0x5a, 0x1c,
266 0x52, 0x2a, 0xe5, 0x81, 0x60, 0xda, 0xc8, 0x70, 0xdf, 0xbd, 0x86, 0x06,
267 0xe4, 0xec, 0xa0, 0x89, 0x2a, 0xe5, 0x1c, 0x87, 0x34, 0xf5, 0xb7, 0x71,
268 0x2b, 0xcd, 0x3d, 0xe3, 0x32, 0x5e, 0xc2, 0x5f, 0x07, 0xd4, 0xef, 0x94,
269 0x33, 0x94, 0xd5, 0xe7, 0xb3, 0x84, 0x10, 0x05, 0xa3, 0xbd, 0x1a, 0x3e,
270 0x4d, 0x27, 0x06, 0x1d, 0x54, 0xd2, 0x44, 0x58, 0x24, 0xf8, 0x51, 0x17,
271 0xd0, 0xf6, 0x97, 0x12, 0x84, 0xa8, 0xc9, 0x7a, 0x42, 0x50, 0xb9, 0x9b,
272 };
273
274 /* 4096 / 512 | 417 | 2887 | 86 */
275 static const uint8_t smallprime_512[] = {
276 0x09, 0x62, 0x07, 0xfc, 0xcb, 0x19, 0xd6, 0x75, 0x8e, 0x37, 0x4b, 0xee,
277 0x6c, 0x37, 0x09, 0xaf, 0x0a, 0x54, 0xa9, 0x82, 0xbf, 0x90, 0x14, 0xe4,
278 0x50, 0xb7, 0x48, 0x18, 0x13, 0xb7, 0x30, 0x5b, 0x4c, 0x25, 0xf0, 0xe2,
279 0xea, 0x6e, 0x2b, 0x56, 0xf9, 0x1e, 0x59, 0x92, 0x14, 0x2d, 0x21, 0x6e,
280 0xae, 0xb2, 0xec, 0xe0, 0x05, 0xfa, 0x0d, 0x18, 0xef, 0xeb, 0x78, 0xef,
281 0xc3, 0x41, 0xf3, 0x1f, 0x78, 0x3e, 0xe4, 0x4a, 0xc5, 0xef, 0x5d, 0xfe,
282 0x35, 0x57, 0x91, 0x28, 0x21, 0x06, 0x15, 0x6c, 0x64, 0xd1, 0x67, 0xa5,
283 0x42, 0x1c, 0xfe, 0xc3, 0x3c, 0xbb, 0xd3, 0x88, 0x38, 0x0b, 0xe8, 0x54,
284 0x14, 0x9f, 0xb6, 0x5c, 0x08, 0xe7, 0x9c, 0xd0, 0x4e, 0xc4, 0x8b, 0x45,
285 0x62, 0x8e, 0xe6, 0x7f, 0x5c, 0x6f, 0xb0, 0x18, 0x18, 0xfa, 0x1f, 0xf7,
286 0x32, 0x24, 0x0c, 0x0b, 0xb1, 0xc7, 0xfe, 0xc1, 0x4c, 0x48, 0x23, 0x4c,
287 0x6f, 0xc3, 0xe0, 0x75, 0x76, 0x4f, 0x63, 0xc0, 0x26, 0x83, 0x61, 0x83,
288 0x1d, 0x89, 0x60, 0xf2, 0x4b, 0x23, 0x7e, 0x96, 0xc2, 0xca, 0xba, 0x4c,
289 0x1a, 0x21, 0x23, 0xff, 0x33, 0xa4, 0x9b, 0xca, 0x39, 0x49, 0xe8, 0xab,
290 0xad, 0xde, 0x06, 0xda, 0xc5, 0x70, 0x3d, 0x16, 0xdb, 0x76, 0x77, 0xdf,
291 0x2b, 0x0c, 0xe2, 0xc7, 0x84, 0x85, 0xeb, 0xd5, 0xe6, 0x9b, 0xd8, 0x0a,
292 0x18, 0x48, 0xa9, 0xfe, 0x28, 0x9c, 0xa2, 0xba, 0x66, 0x4a, 0x68, 0x7b,
293 0x3f, 0x05, 0x40, 0x15, 0x6e, 0x67, 0xae, 0x67, 0x69, 0xc0, 0x9e, 0x11,
294 0xce, 0x56, 0x73, 0x57, 0xf5, 0xa5, 0x76, 0xa4, 0x8e, 0xed, 0xd9, 0x63,
295 0x35, 0xe6, 0x28, 0x77, 0xc7, 0x3a, 0x65, 0x40, 0x8b, 0x71, 0x48, 0x4e,
296 0xd0, 0xf1, 0x1d, 0x20, 0xd5, 0x1e, 0x8e, 0x54, 0x67, 0xa1, 0xe4, 0xc0,
297 0x9b, 0xf7, 0x29, 0xba, 0x16, 0x9f, 0xcf, 0xdb, 0xa8, 0xb5, 0x5c, 0x4c,
298 0x5b, 0x68, 0x2f, 0xaa, 0x28, 0x71, 0x9b, 0x9f, 0x49, 0xbf, 0x36, 0x2d,
299 0x9f, 0x03, 0xee, 0x6b, 0xde, 0x79, 0x01, 0xe9, 0x40, 0xe2, 0x49, 0xb4,
300 0x1c, 0x93, 0xb9, 0xab, 0x05, 0x4a, 0xbc, 0xab, 0x10, 0x9a, 0xf1, 0x2a,
301 0xa6, 0x53, 0x5e, 0xd8, 0xf6, 0x23, 0xab, 0xfd, 0x31, 0x2a, 0xaa, 0x08,
302 0x4a, 0x74, 0x8f, 0x86, 0x53, 0x83, 0xbc, 0xe3, 0x15, 0xdc, 0x0d, 0x45,
303 0xcb, 0x89, 0x50, 0x8d, 0xec, 0xa9, 0x3b, 0xda, 0x22, 0xf0, 0xe7, 0x7a,
304 0x4f, 0xea, 0xa2, 0xa7, 0x90, 0xe0, 0x0e, 0x5a, 0xda, 0x9b, 0xbb, 0x9a,
305 0xe7, 0xd5, 0xfb, 0x63, 0x54, 0xa2, 0x52, 0xda, 0x7d, 0xc2, 0x6e, 0x6a,
306 0xc2, 0xd7, 0xa6, 0x42, 0xea, 0xbf, 0x48, 0x12, 0xe6, 0x4a, 0xe1, 0x95,
307 0xbf, 0x29, 0xcc, 0x9e, 0xe0, 0x25, 0x84, 0xb7, 0x74, 0xdc, 0xb1, 0x12,
308 0x91, 0x57, 0xbf, 0x52, 0x43, 0x8f, 0xb7, 0xb7, 0xcd, 0x6a, 0x78, 0x24,
309 0xa7, 0x41, 0x8b, 0xcc, 0x65, 0x83, 0x05, 0x8e, 0xc2, 0xf0, 0x69, 0x28,
310 0xe4, 0x42, 0x62, 0x37, 0x98, 0xb5, 0x03, 0xf6, 0x75, 0x1d, 0xce, 0xe2,
311 0xc0, 0x1f, 0x39, 0xac, 0xb0, 0xfb, 0x47, 0x8f, 0x6e, 0x8b, 0x16, 0xa3,
312 0x0f, 0xe8, 0x21, 0x9b, 0x8e, 0x67, 0x04, 0xc7, 0x26, 0xb6, 0x03, 0xe1,
313 0x00, 0x09, 0xf6, 0x77, 0x76, 0x46, 0x51, 0x41, 0x57, 0x0d, 0x4b, 0x4c,
314 0x2a, 0x30, 0xdb, 0x84, 0x02, 0x6f, 0x93, 0x4b, 0x81, 0xf0, 0xd5, 0xe9,
315 0x85, 0xc9, 0x75, 0xd6, 0xa9, 0x07, 0x5a, 0x41, 0xd4, 0x17, 0xc6, 0xd9,
316 0x93, 0xcb, 0x49, 0x73, 0xcb, 0xe5, 0x12, 0xa6, 0x7d, 0xb3, 0x1f, 0x6a,
317 0xec, 0x8c, 0xc3, 0xe9, 0xe5, 0xeb, 0xdc, 0x1e, 0xb7, 0xb4, 0x74, 0x54,
318 0x51, 0x52, 0xa1, 0x56, 0xd5, 0xac, 0x58, 0x7d,
319 };
320
321 static const struct smallprime smallprimes[] = {
322 { .data = smallprime_8, .length = sizeof(smallprime_8) },
323 { .data = smallprime_16, .length = sizeof(smallprime_16) },
324 { .data = smallprime_32, .length = sizeof(smallprime_32) },
325 { .data = smallprime_48, .length = sizeof(smallprime_48) },
326 { .data = smallprime_64, .length = sizeof(smallprime_64) },
327 { .data = smallprime_72, .length = sizeof(smallprime_72) },
328 { .data = smallprime_96, .length = sizeof(smallprime_96) },
329 { .data = smallprime_128, .length = sizeof(smallprime_128) },
330 { .data = smallprime_184, .length = sizeof(smallprime_184) },
331 { .data = smallprime_192, .length = sizeof(smallprime_192) },
332 { .data = smallprime_256, .length = sizeof(smallprime_256) },
333 { .data = smallprime_384, .length = sizeof(smallprime_384) },
334 { .data = smallprime_512, .length = sizeof(smallprime_512) },
335 };
336
337 /*
338 * Search the small prime closed to the given input bytes size
339 *
340 * @size Size in bytes
341 * @prime [out] Output predefined small prime
342 */
search_smallprime(size_t size,struct caambuf * prime)343 static void search_smallprime(size_t size, struct caambuf *prime)
344 {
345 size_t nb_elem = ARRAY_SIZE(smallprimes);
346 size_t idx = 0;
347 size_t psize = 0;
348
349 for (; idx < nb_elem; idx++) {
350 psize = smallprimes[idx].length;
351
352 if (psize == size) {
353 /* Found a predefined prime */
354 RSA_TRACE("Found prime idx %zu", idx);
355 prime->data = (uint8_t *)smallprimes[idx].data;
356 prime->length = psize;
357 prime->paddr = virt_to_phys(prime->data);
358 break;
359 }
360 }
361 }
362
363 /*
364 * Build the descriptor preparing the CAAM global variables used during the
365 * prime generation
366 *
367 * @desc [out] Descriptor built
368 * @data Prime generation data
369 * @small_prime Pre-generated small prime value
370 * @desc_prime Physical address of the prime generator descriptor
371 */
do_desc_setup(uint32_t * desc,struct prime_data_rsa * data,const struct caambuf * small_prime,const paddr_t desc_prime)372 static void do_desc_setup(uint32_t *desc, struct prime_data_rsa *data,
373 const struct caambuf *small_prime,
374 const paddr_t desc_prime)
375 {
376 size_t key_size = data->key_size / 8;
377
378 /*
379 * Referring to FIPS.186-4, B.3.3 (step 4.7)
380 * Maximum tries = 5 * (nlen / 2)
381 * Where nlen is the RSA security length in bit
382 */
383 caam_desc_init(desc);
384 caam_desc_add_word(desc, DESC_HEADER(0));
385
386 caam_desc_add_word(desc, MATH(ADD, IMM_DATA, ZERO, SOL, 4));
387 caam_desc_add_word(desc, 5 * (data->key_size / 2));
388
389 /*
390 * Referring to FIPS.186-4, Table C.2
391 * Get the number Miller-Rabin test interation function
392 * of the prime number size
393 */
394 caam_desc_add_word(desc, MATH(ADD, IMM_DATA, ZERO, SIL, 4));
395 if ((key_size / 2) > (MR_PRIME_SIZE / 8))
396 caam_desc_add_word(desc, 0x4);
397 else
398 caam_desc_add_word(desc, 0x5);
399
400 /*
401 * Preload PKHA A2 with the sqrt_value array (step 4.4)
402 * Do it once, not at each loop
403 */
404 caam_desc_add_word(desc, FIFO_LD(CLASS_1, PKHA_A2, NOACTION,
405 key_size / 2));
406 caam_desc_add_ptr(desc, virt_to_phys((void *)sqrt_value));
407
408 if (data->era >= 8 && small_prime->paddr) {
409 /*
410 * Preload PKHA B2 with small prime predefined
411 * (preload only prime size requested)
412 *
413 * Before Era 8, the PRIME TEST function overwrites PKHA B2
414 * hence PKHA B2 must be reloaded if new prime tentative after
415 * PRIME TEST on Era < 8
416 */
417 caam_desc_add_word(desc, FIFO_LD(CLASS_1, PKHA_B2, NOACTION,
418 small_prime->length));
419 caam_desc_add_ptr(desc, small_prime->paddr);
420 }
421
422 /* Set the High order bit used to turn on MSB in prime candidate */
423 caam_desc_add_word(desc, MATHI_OP1(SHIFT_L, ONE, 0x3F, REG2, 8));
424
425 /* Load PKHA N Size with the prime size */
426 caam_desc_add_word(desc, LD_IMM(CLASS_1, REG_PKHA_N_SIZE, 4));
427 caam_desc_add_word(desc, key_size / 2);
428
429 /*
430 * Set the number of maximum tries because of generated value
431 * is too small. This value is used to not lock the system
432 * in prime number generation
433 */
434 caam_desc_add_word(desc, MATH(ADD, ZERO, IMM_DATA, DPOVRD, 4));
435 caam_desc_add_word(desc, MAX_RETRY_PRIME_GEN);
436
437 /* Jump to the next descriptor desc */
438 caam_desc_add_word(desc, JUMP_NOTLOCAL(CLASS_NO, ALL_COND_TRUE,
439 JMP_COND(NONE)));
440 caam_desc_add_ptr(desc, desc_prime);
441
442 RSA_DUMPDESC(desc);
443 cache_operation(TEE_CACHECLEAN, (void *)sqrt_value, data->p->length);
444 }
445
446 /*
447 * Build the descriptor generating a prime
448 *
449 * @desc [out] Descriptor built
450 * @data Prime generation data
451 * @small_prime Pre-generated small prime value
452 * @do_prime_q Generate Prime Q
453 * @desc_next Physical address of the next descriptor (can be NULL)
454 */
do_desc_prime(uint32_t * desc,struct prime_data_rsa * data,const struct caambuf * small_prime,bool do_prime_q,const paddr_t desc_next)455 static void do_desc_prime(uint32_t *desc, struct prime_data_rsa *data,
456 const struct caambuf *small_prime, bool do_prime_q,
457 const paddr_t desc_next)
458 {
459 uint32_t desclen = 0;
460 uint32_t retry_too_small = 0;
461 uint32_t retry_new_number = 0;
462 uint32_t retry_new_mr_failed = 0;
463 uint32_t retry_mr_test = 0;
464
465 caam_desc_init(desc);
466 caam_desc_add_word(desc, DESC_HEADER(0));
467
468 /* Setup the number of try counter = MAX (counting down) */
469 caam_desc_add_word(desc, MATH(ADD, SOL, ZERO, VSOL, 4));
470
471 retry_new_mr_failed = caam_desc_get_len(desc);
472 if (data->era < 8 && small_prime->paddr) {
473 /*
474 * Preload PKHA B2 with small prime predefined
475 * (preload only prime size requested)
476 */
477 caam_desc_add_word(desc, FIFO_LD(CLASS_1, PKHA_B2, NOACTION,
478 small_prime->length));
479 caam_desc_add_ptr(desc, small_prime->paddr);
480 }
481
482 retry_new_number = caam_desc_get_len(desc);
483 /* Decrement the number of try */
484 caam_desc_add_word(desc, MATH(SUB, VSOL, ONE, VSOL, 4));
485 /* Exceed retry count - exit with RSA_TRY_FAIL error */
486 caam_desc_add_word(desc,
487 HALT_USER(ALL_COND_TRUE, MATH_N, RSA_TRY_FAIL));
488
489 retry_too_small = caam_desc_get_len(desc);
490 /* Check internal limit on random value generation */
491 caam_desc_add_word(desc, MATH(SUB, DPOVRD, ONE, DPOVRD, 4));
492 caam_desc_add_word(desc,
493 HALT_USER(ALL_COND_TRUE, MATH_Z, RETRY_TOO_SMALL));
494
495 /*
496 * Step 4.2 - Obtain a string p of (nlen/2) bits
497 * Step 4.3 - if (p is not odd) then p = p + 1
498 */
499 /* Generate 16 random bytes load into DECO fifo */
500 caam_desc_add_word(desc, LD_IMM(CLASS_NO, REG_NFIFO, 4));
501 caam_desc_add_word(desc, NFIFO_PAD(DECO, NFIFO_LC1, MSG, RND, 16));
502
503 /* Get the DECO Input fifo 8 MSB and force on high bit */
504 caam_desc_add_word(desc, MATH(OR, REG2, IFIFO, REG0, 8));
505 /* Get the DECO Input fifo 8 LSB and force it be be odd */
506 caam_desc_add_word(desc, MATH(OR, ONE, IFIFO, REG1, 8));
507 /* Move the MSB and LSB into IFIFO */
508 caam_desc_add_word(desc, MOVE(MATH_REG0, IFIFO, 0, 16));
509 /* Send the 8 MSB into PKHA N */
510 caam_desc_add_word(desc, LD_IMM(CLASS_NO, REG_NFIFO, 4));
511 caam_desc_add_word(desc, NFIFO_NOPAD(C1, 0, IFIFO, PKHA_N, 8));
512
513 /*
514 * Generate the "middle" random bytes and start them
515 * on their way into PKHA N
516 */
517 caam_desc_add_word(desc, LD_IMM(CLASS_NO, REG_NFIFO, 8));
518 caam_desc_add_word(desc, NFIFO_PAD(C1, 0, PKHA_N, RND, 0));
519 caam_desc_add_word(desc, (data->key_size / 8 / 2) - 16);
520
521 /* And send the 8 LSB into PKHA N */
522 caam_desc_add_word(desc, LD_IMM(CLASS_NO, REG_NFIFO, 4));
523 caam_desc_add_word(desc, NFIFO_NOPAD(C1, NFIFO_FC1, IFIFO, PKHA_N, 8));
524
525 /*
526 * Step 4.4 - if ((prime < (sqrt 2)(2^((nlen / 2) - 1))
527 * ==> retry_too_small
528 */
529 caam_desc_add_word(desc, PKHA_CPY_SSIZE(A2, B0));
530 caam_desc_add_word(desc, PKHA_CPY_SSIZE(B0, A0));
531 caam_desc_add_word(desc, PKHA_OP(MOD_AMODN, A));
532 caam_desc_add_word(desc, PKHA_CPY_SSIZE(A2, B0));
533 caam_desc_add_word(desc, PKHA_F2M_OP(MOD_ADD_A_B, B));
534
535 desclen = caam_desc_get_len(desc);
536 caam_desc_add_word(desc, JUMP_CNO_LOCAL(ANY_COND_FALSE,
537 JMP_COND(PKHA_IS_ZERO),
538 retry_too_small - desclen));
539
540 /*
541 * Step 4.5 - Compute GCD(prime-1, e) and test if = 1 else try
542 * another candidate
543 */
544 caam_desc_add_word(desc, PKHA_CPY_SSIZE(N0, A0));
545 caam_desc_add_word(desc, FIFO_LD_IMM(CLASS_1, PKHA_B, NOACTION, 1));
546 caam_desc_add_word(desc, 0x01);
547 caam_desc_add_word(desc, PKHA_F2M_OP(MOD_ADD_A_B, B));
548 caam_desc_add_word(desc, PKHA_CPY_SSIZE(B0, N0));
549
550 caam_desc_add_word(desc,
551 FIFO_LD(CLASS_1, PKHA_A, NOACTION, data->e->length));
552 caam_desc_add_ptr(desc, data->e->paddr);
553 caam_desc_add_word(desc, PKHA_OP(GCD_A_N, B));
554
555 desclen = caam_desc_get_len(desc);
556 caam_desc_add_word(desc,
557 JUMP_CNO_LOCAL(ANY_COND_FALSE, JMP_COND(PKHA_GCD_1),
558 retry_new_number - desclen));
559
560 caam_desc_add_word(desc, PKHA_CPY_SSIZE(N0, A0));
561 caam_desc_add_word(desc, FIFO_LD_IMM(CLASS_1, PKHA_B, NOACTION, 1));
562 caam_desc_add_word(desc, 0x01);
563 caam_desc_add_word(desc, PKHA_F2M_OP(MOD_ADD_A_B, B));
564 caam_desc_add_word(desc, PKHA_CPY_SSIZE(B0, N0));
565
566 /*
567 * Step 4.5.1 - test primality
568 */
569 if (small_prime->paddr) {
570 caam_desc_add_word(desc, PKHA_CPY_SSIZE(B2, A0));
571 caam_desc_add_word(desc, PKHA_OP(GCD_A_N, B));
572 desclen = caam_desc_get_len(desc);
573 caam_desc_add_word(desc,
574 JUMP_CNO_LOCAL(ANY_COND_FALSE,
575 JMP_COND(PKHA_GCD_1),
576 retry_new_number - desclen));
577 }
578
579 /* Generate 8 random bytes 'miller-rabin seed' */
580 /* Load the number of Miller-Rabin test iteration */
581 caam_desc_add_word(desc, MATH(ADD, SIL, ZERO, VSIL, 4));
582 retry_mr_test = caam_desc_get_len(desc);
583 caam_desc_add_word(desc, LD_IMM(CLASS_NO, REG_NFIFO, 8));
584 caam_desc_add_word(desc, NFIFO_PAD(C1, NFIFO_FC1, PKHA_A, RND, 0));
585 caam_desc_add_word(desc, (data->key_size / 8 / 2));
586 caam_desc_add_word(desc, FIFO_LD_IMM(CLASS_1, PKHA_B, NOACTION, 1));
587 caam_desc_add_word(desc, 0x01);
588 caam_desc_add_word(desc, PKHA_OP(MR_PRIMER_TEST, B));
589
590 desclen = caam_desc_get_len(desc);
591 caam_desc_add_word(desc, JUMP_CNO_LOCAL(ANY_COND_FALSE,
592 JMP_COND(PKHA_IS_PRIME),
593 retry_new_mr_failed - desclen));
594 caam_desc_add_word(desc, MATH(SUB, VSIL, ONE, VSIL, 4));
595
596 desclen = caam_desc_get_len(desc);
597 caam_desc_add_word(desc,
598 JUMP_CNO_LOCAL(ALL_COND_FALSE,
599 JMP_COND(MATH_N) | JMP_COND(MATH_Z),
600 retry_mr_test - desclen));
601
602 /* Save prime generated */
603 caam_desc_add_word(desc,
604 FIFO_ST(CLASS_NO, PKHA_N, (data->key_size / 8 / 2)));
605
606 if (do_prime_q)
607 caam_desc_add_ptr(desc, data->q->paddr);
608 else
609 caam_desc_add_ptr(desc, data->p->paddr);
610
611 if (desc_next) {
612 /* Jump to the next descriptor desc */
613 caam_desc_add_word(desc, JUMP_NOTLOCAL(CLASS_NO, ALL_COND_TRUE,
614 JMP_COND(NONE)));
615 caam_desc_add_ptr(desc, desc_next);
616 }
617
618 RSA_DUMPDESC(desc);
619 }
620
621 /*
622 * Build the descriptor to check primes p and q not too closed.
623 * Check the upper 100 bits with operation:
624 * |p - q| <= 2^(nlen/2-100)
625 *
626 * @desc [out] Descriptor built
627 * @p Prime P
628 * @max_n Max N built with 0xFFFF...
629 * @desc_new_q Physical address to generate a new Q value
630 */
do_checks_primes(uint32_t * desc,const struct caambuf * p,const struct caambuf * max_n,const paddr_t desc_new_q,size_t key_size)631 static void do_checks_primes(uint32_t *desc, const struct caambuf *p,
632 const struct caambuf *max_n,
633 const paddr_t desc_new_q,
634 size_t key_size)
635 {
636 const uint8_t check_len = 16; /* Check 128 bits */
637
638 caam_desc_init(desc);
639 caam_desc_add_word(desc, DESC_HEADER(0));
640
641 /* Load prime p */
642 caam_desc_add_word(desc, FIFO_LD(CLASS_1, PKHA_B, NOACTION, key_size));
643 caam_desc_add_ptr(desc, p->paddr);
644
645 /* Retrieve Q from PKHA N, previously computed */
646 caam_desc_add_word(desc, PKHA_CPY_SSIZE(N0, A0));
647
648 /* Calculate p - q, need a modulus of size prime p filled with 0xFF */
649 caam_desc_add_word(desc,
650 FIFO_LD(CLASS_1, PKHA_N, NOACTION, max_n->length));
651 caam_desc_add_ptr(desc, max_n->paddr);
652
653 /* PKHA_B = p - q */
654 caam_desc_add_word(desc, PKHA_OP(MOD_SUB_A_B, B));
655
656 /* Unload PKHA register B to output Data FIFO */
657 caam_desc_add_word(desc, LD_NOCLASS_IMM(REG_CHA_CTRL, 4));
658 caam_desc_add_word(desc, CCTRL_ULOAD_PKHA_B);
659
660 /* Get the first 128 bits in MATH 0 */
661 caam_desc_add_word(desc, MOVE_WAIT(OFIFO, MATH_REG0, 0, check_len));
662
663 /*
664 * We now need to trash the rest of the result.
665 * We started with 128, 192, or 256 bytes in the OFIFO before we moved
666 * check_len bytes into MATH registers.
667 */
668 if (key_size > 128 + (size_t)check_len) {
669 caam_desc_add_word(desc, MOVE(OFIFO, C1_CTX_REG, 0, check_len));
670 caam_desc_add_word(desc, MOVE(OFIFO, C1_CTX_REG, 0,
671 (key_size - 128 - check_len)));
672 } else if (key_size > check_len) {
673 caam_desc_add_word(desc, MOVE(OFIFO, C1_CTX_REG, 0,
674 (key_size - check_len)));
675 }
676
677 /*
678 * In MATH registers we have the p - q value modulo 0xFFFFF...
679 * Check the upper 100 bits are either zero or one meaning
680 * q is too close to p
681 */
682 /* Check first 64 bits if not 0's check if 1's */
683 caam_desc_add_word(desc, MATH(ADD, ZERO, REG0, REG0, 8));
684 caam_desc_add_word(desc,
685 JUMP_CNO_LOCAL(ANY_COND_FALSE, JMP_COND(MATH_Z), 6));
686 /* First 64 bits are 0's, check next 36 bits */
687 caam_desc_add_word(desc, MATH(AND, REG1, IMM_DATA, REG1, 8));
688 caam_desc_add_word(desc, UINT32_MAX);
689 caam_desc_add_word(desc, 0xF0000000);
690
691 /* Next 36 bits are 0 */
692 caam_desc_add_word(desc,
693 JUMP_CNO_LOCAL(ALL_COND_TRUE, JMP_COND(MATH_Z), 10));
694 /* Exit status GOOD Q */
695 caam_desc_add_word(desc, HALT_USER(ALL_COND_TRUE, NONE, STATUS_GOOD_Q));
696
697 /* Check if 100 bits are 1's */
698 caam_desc_add_word(desc, MATH(ADD, ONE, REG0, REG0, 8));
699 /* Not all 1's exit status GOOD Q */
700 caam_desc_add_word(desc,
701 HALT_USER(ANY_COND_FALSE, MATH_Z, STATUS_GOOD_Q));
702 /* First 64 bits are 1's, check next 36 bits */
703 caam_desc_add_word(desc, MATH(AND, REG1, IMM_DATA, REG1, 8));
704 caam_desc_add_word(desc, UINT32_MAX);
705 caam_desc_add_word(desc, SHIFT_U32(0xF, 28));
706
707 /* Use only 4 bytes of immediate data even is operation is 8 bytes */
708 caam_desc_add_word(desc, MATH(ADD, REG1, IMM_DATA, REG1, 8) | MATH_IFB);
709 caam_desc_add_word(desc, SHIFT_U32(1, 28));
710
711 /* Not all 1's exit status GOOD Q */
712 caam_desc_add_word(desc,
713 HALT_USER(ANY_COND_FALSE, MATH_Z, STATUS_GOOD_Q));
714
715 if (desc_new_q) {
716 caam_desc_add_word(desc, JUMP_NOTLOCAL(CLASS_NO, ALL_COND_TRUE,
717 JMP_COND(NONE)));
718 caam_desc_add_ptr(desc, desc_new_q);
719 }
720
721 RSA_DUMPDESC(desc);
722 }
723
724 /*
725 * Run the Primes descriptor.
726 *
727 * @desc Descriptor built
728 * @prime Prime generation data
729 */
run_primes(uint32_t * desc,struct prime_data_rsa * data)730 static enum caam_status run_primes(uint32_t *desc, struct prime_data_rsa *data)
731 {
732 enum caam_status retstatus = CAAM_FAILURE;
733 struct caam_jobctx jobctx = { };
734
735 cache_operation(TEE_CACHEFLUSH, data->p->data, data->p->length);
736
737 if (data->q)
738 cache_operation(TEE_CACHEFLUSH, data->q->data, data->q->length);
739
740 jobctx.desc = desc;
741 retstatus = caam_jr_enqueue(&jobctx, NULL);
742
743 if (data->q && retstatus == CAAM_JOB_STATUS) {
744 /*
745 * Expect to have a retstatus == CAAM_JOB_STATUS, where
746 * job status == STATUS_GOOD_Q
747 */
748 RSA_TRACE("Check Prime Q Status 0x%08" PRIx32, jobctx.status);
749
750 if (JRSTA_GET_HALT_USER(jobctx.status) == STATUS_GOOD_Q) {
751 cache_operation(TEE_CACHEINVALIDATE, data->p->data,
752 data->p->length);
753 cache_operation(TEE_CACHEINVALIDATE, data->q->data,
754 data->q->length);
755
756 RSA_DUMPBUF("Prime P", data->p->data, data->p->length);
757 RSA_DUMPBUF("Prime Q", data->q->data, data->q->length);
758 retstatus = CAAM_NO_ERROR;
759 }
760 } else if (retstatus == CAAM_NO_ERROR && !data->q) {
761 cache_operation(TEE_CACHEINVALIDATE, data->p->data,
762 data->p->length);
763
764 RSA_DUMPBUF("Prime", data->p->data, data->p->length);
765 } else if (retstatus != CAAM_NO_ERROR) {
766 RSA_TRACE("Prime Status 0x%08" PRIx32, jobctx.status);
767 }
768
769 return retstatus;
770 }
771
caam_prime_rsa_gen(struct prime_data_rsa * data)772 enum caam_status caam_prime_rsa_gen(struct prime_data_rsa *data)
773 {
774 enum caam_status retstatus = CAAM_FAILURE;
775 struct caambuf small_prime = { };
776 struct caambuf max_n = { };
777 uint32_t *all_descs = NULL;
778 uint32_t *desc_p = NULL;
779 uint32_t *desc_q = NULL;
780 uint32_t *desc_check_p_q = NULL;
781 paddr_t paddr_desc_p = 0;
782 paddr_t paddr_desc_q = 0;
783 paddr_t paddr_desc_check_p_q = 0;
784 size_t size_all_descs = 0;
785 size_t nb_tries = RSA_MAX_TRIES_PRIMES;
786 size_t key_size = data->key_size / 8 / 2;
787
788 /* Allocate the job used to prepare the operation */
789 if (data->q) {
790 size_all_descs = SETUP_RSA_DESC_ENTRIES +
791 GEN_RSA_DESC_ENTRIES * 2 +
792 CHECK_P_Q_DESC_ENTRIES;
793
794 retstatus = caam_calloc_buf(&max_n, key_size + 1);
795 if (retstatus != CAAM_NO_ERROR)
796 goto end_gen_prime;
797
798 /* Set the max_n with 0xFFF... to operate the check P and Q */
799 memset(max_n.data, UINT8_MAX, max_n.length);
800 cache_operation(TEE_CACHECLEAN, max_n.data, max_n.length);
801 } else {
802 size_all_descs = SETUP_RSA_DESC_ENTRIES + GEN_RSA_DESC_ENTRIES;
803 }
804
805 all_descs = caam_calloc_desc(size_all_descs);
806 if (!all_descs) {
807 retstatus = CAAM_OUT_MEMORY;
808 goto end_gen_prime;
809 }
810
811 /* Descriptor Prime P */
812 desc_p = all_descs + SETUP_RSA_DESC_ENTRIES;
813 paddr_desc_p = virt_to_phys(desc_p);
814 if (!paddr_desc_p) {
815 retstatus = CAAM_FAILURE;
816 goto end_gen_prime;
817 }
818
819 /*
820 * Search predefined prime in the small_prime list, if the
821 * small prime is not found in the list, continue anyway
822 * but prime will be probably not so strong
823 */
824 search_smallprime(key_size, &small_prime);
825
826 RSA_TRACE("Do prime of %zu bytes (security len %zu bits) (ERA=%" PRId8
827 ")",
828 key_size, data->key_size, data->era);
829
830 do_desc_setup(all_descs, data, &small_prime, paddr_desc_p);
831
832 if (data->q) {
833 /* Descriptor Prime Q */
834 desc_q = desc_p + GEN_RSA_DESC_ENTRIES;
835 paddr_desc_q =
836 paddr_desc_p + DESC_SZBYTES(GEN_RSA_DESC_ENTRIES);
837
838 /* Descriptor Check Primes P & Q */
839 desc_check_p_q = desc_q + GEN_RSA_DESC_ENTRIES;
840 paddr_desc_check_p_q =
841 paddr_desc_q + DESC_SZBYTES(GEN_RSA_DESC_ENTRIES);
842
843 /* Generate Prime P and Q then check Q not too close than P */
844 do_desc_prime(desc_p, data, &small_prime, false, paddr_desc_q);
845
846 do_desc_prime(desc_q, data, &small_prime, true,
847 paddr_desc_check_p_q);
848
849 do_checks_primes(desc_check_p_q, data->p, &max_n, paddr_desc_q,
850 key_size);
851 } else {
852 do_desc_prime(desc_p, data, &small_prime, false, 0);
853 }
854
855 cache_operation(TEE_CACHECLEAN, small_prime.data, data->p->length);
856 cache_operation(TEE_CACHECLEAN, data->e->data, data->e->length);
857 cache_operation(TEE_CACHECLEAN, (void *)all_descs,
858 DESC_SZBYTES(size_all_descs));
859
860 do {
861 retstatus = run_primes(all_descs, data);
862 } while (--nb_tries && retstatus != CAAM_NO_ERROR);
863
864 end_gen_prime:
865 caam_free_desc(&all_descs);
866 caam_free_buf(&max_n);
867
868 return retstatus;
869 }
870