xref: /optee_os/core/drivers/crypto/caam/acipher/caam_prime_rsa.c (revision ccbcceeb73c188a196660485bfff560391e476de)
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