xref: /freebsd/crypto/libecc/src/examples/sig/rsa/rsa.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1 *f0865ec9SKyle Evans /*
2 *f0865ec9SKyle Evans  *  Copyright (C) 2021 - This file is part of libecc project
3 *f0865ec9SKyle Evans  *
4 *f0865ec9SKyle Evans  *  Authors:
5 *f0865ec9SKyle Evans  *      Ryad BENADJILA <ryadbenadjila@gmail.com>
6 *f0865ec9SKyle Evans  *      Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7 *f0865ec9SKyle Evans  *
8 *f0865ec9SKyle Evans  *  This software is licensed under a dual BSD and GPL v2 license.
9 *f0865ec9SKyle Evans  *  See LICENSE file at the root folder of the project.
10 *f0865ec9SKyle Evans  */
11 *f0865ec9SKyle Evans #include "rsa.h"
12 *f0865ec9SKyle Evans #include "rsa_tests.h"
13 *f0865ec9SKyle Evans 
14 *f0865ec9SKyle Evans 
15 *f0865ec9SKyle Evans /* We include the rand external dependency because we have to generate
16 *f0865ec9SKyle Evans  * some random data for the padding.
17 *f0865ec9SKyle Evans  */
18 *f0865ec9SKyle Evans #include <libecc/external_deps/rand.h>
19 *f0865ec9SKyle Evans /* We include the printf external dependency for printf output */
20 *f0865ec9SKyle Evans #include <libecc/external_deps/print.h>
21 *f0865ec9SKyle Evans /* We include our common helpers */
22 *f0865ec9SKyle Evans #include "../common/common.h"
23 *f0865ec9SKyle Evans 
24 *f0865ec9SKyle Evans 
25 *f0865ec9SKyle Evans /*
26 *f0865ec9SKyle Evans  * The purpose of this example is to implement the RSA
27 *f0865ec9SKyle Evans  * related algorithms as per RFC 8017 and ISO/IEC 9796-2 based
28 *f0865ec9SKyle Evans  * on libecc arithmetic primitives.
29 *f0865ec9SKyle Evans  *
30 *f0865ec9SKyle Evans  * XXX: Please be aware that libecc has been designed for Elliptic
31 *f0865ec9SKyle Evans  * Curve cryptography, and as so the arithmetic primitives are
32 *f0865ec9SKyle Evans  * not optimized for big numbers >= 1024 bits usually used for RSA.
33 *f0865ec9SKyle Evans  * Additionnaly, a hard limit of our NN values makes it impossible
34 *f0865ec9SKyle Evans  * to exceed ~5300 bits in the best case (words of size 64 bits).
35 *f0865ec9SKyle Evans  *
36 *f0865ec9SKyle Evans  * All in all, please see this as a proof of concept of implementing
37 *f0865ec9SKyle Evans  * RFC 8017 rather than a production code. Use it at your own risk!
38 *f0865ec9SKyle Evans  *
39 *f0865ec9SKyle Evans  * !! DISCLAIMER !!
40 *f0865ec9SKyle Evans  * ================
41 *f0865ec9SKyle Evans  * Although some efforts have been put on providing a clean code and although many of
42 *f0865ec9SKyle Evans  * the underlying arithmetic primitives are constant time, only basic efforts have
43 *f0865ec9SKyle Evans  * been deployed to prevent advanced side channels (e.g. to protect the private values
44 *f0865ec9SKyle Evans  * against elaborate microarchitectural side-channels and so on). The modular exponentation
45 *f0865ec9SKyle Evans  * uses a Montgomery Ladder, and message blinding is performed to mitigate basic SCA.
46 *f0865ec9SKyle Evans  * Please note that the modular exponentation is NOT constant time wrt the MSB of
47 *f0865ec9SKyle Evans  * the private exponent, which should be OK in the general case as this leak is less
48 *f0865ec9SKyle Evans  * critical than for DSA and ECDSA nonces in scalar multiplication (raising HNP issues
49 *f0865ec9SKyle Evans  * in these last cases).
50 *f0865ec9SKyle Evans  * Optionally, when BLINDING=1 is activated, exponent blinding is used by adding a
51 *f0865ec9SKyle Evans  * "small" (128 bits) multiple of the "order" (this is left as optional because of
52 *f0865ec9SKyle Evans  * the big impacts on performance), somehow limiting the modular exponentiation MSB
53 *f0865ec9SKyle Evans  * issue at the expense of performance.
54 *f0865ec9SKyle Evans  *
55 *f0865ec9SKyle Evans  * Padding oracles (Bleichenbacher, Manger) in RSA PKCS#1 v1.5 and RSA-OAEP decryption
56 *f0865ec9SKyle Evans  * primitives are taken into account, although no absolute guarantee can be made on this
57 *f0865ec9SKyle Evans  * (and mostly: these oracles also heavily depend on what the upper layer callers do).
58 *f0865ec9SKyle Evans  *
59 *f0865ec9SKyle Evans  * Fault injection attacks "a la Bellcore" are protected using a sanity check that
60 *f0865ec9SKyle Evans  * the exponentiation to the public exponent provides the same input as the operation
61 *f0865ec9SKyle Evans  * using the private exponent.
62 *f0865ec9SKyle Evans  *
63 *f0865ec9SKyle Evans  * !!NOTE: only the *_hardened* suffixed APIs are protected, the non suffixed ones are
64 *f0865ec9SKyle Evans  * *NOT* protected. This is mainly due to the fact that the protections use the public
65 *f0865ec9SKyle Evans  * key while the RFC APIs handling private operations only take the private key as
66 *f0865ec9SKyle Evans  * input. Hence, please *USE* the *_hardened* APIs if unsure about your usage context!
67 *f0865ec9SKyle Evans  *
68 *f0865ec9SKyle Evans  * Also, as for all other libecc primitives, beware of randomness sources. By default,
69 *f0865ec9SKyle Evans  * the library uses the OS random sources (e.g. "/dev/urandom"), but the user
70 *f0865ec9SKyle Evans  * is encouraged to adapt the ../external_deps/rand.c source file to combine
71 *f0865ec9SKyle Evans  * multiple sources and add entropy there depending on the context where this
72 *f0865ec9SKyle Evans  * code is integrated. The security level of all the cryptographic primitives
73 *f0865ec9SKyle Evans  * heavily relies on random sources quality.
74 *f0865ec9SKyle Evans  *
75 *f0865ec9SKyle Evans  * All-in-all, this piece of code can be useful in some contexts, or risky to
76 *f0865ec9SKyle Evans  * use in other sensitive ones where advanced side-channels or fault attacks
77 *f0865ec9SKyle Evans  * have to be considered. Use this RSA code knowingly and at your own risk!
78 *f0865ec9SKyle Evans  *
79 *f0865ec9SKyle Evans  */
80 *f0865ec9SKyle Evans 
rsa_import_pub_key(rsa_pub_key * pub,const u8 * n,u16 nlen,const u8 * e,u16 elen)81 *f0865ec9SKyle Evans int rsa_import_pub_key(rsa_pub_key *pub, const u8 *n,
82 *f0865ec9SKyle Evans                        u16 nlen, const u8 *e, u16 elen)
83 *f0865ec9SKyle Evans {
84 *f0865ec9SKyle Evans 	int ret;
85 *f0865ec9SKyle Evans 
86 *f0865ec9SKyle Evans 	MUST_HAVE((pub != NULL), ret, err);
87 *f0865ec9SKyle Evans 
88 *f0865ec9SKyle Evans 	/* Import our big numbers */
89 *f0865ec9SKyle Evans 	ret = nn_init_from_buf(&(pub->n), n, nlen); EG(ret, err);
90 *f0865ec9SKyle Evans 	ret = nn_init_from_buf(&(pub->e), e, elen);
91 *f0865ec9SKyle Evans 
92 *f0865ec9SKyle Evans err:
93 *f0865ec9SKyle Evans 	if(ret && (pub != NULL)){
94 *f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(pub, 0, sizeof(rsa_pub_key)));
95 *f0865ec9SKyle Evans 	}
96 *f0865ec9SKyle Evans 
97 *f0865ec9SKyle Evans 	return ret;
98 *f0865ec9SKyle Evans }
99 *f0865ec9SKyle Evans 
rsa_import_simple_priv_key(rsa_priv_key * priv,const u8 * n,u16 nlen,const u8 * d,u16 dlen,const u8 * p,u16 plen,const u8 * q,u16 qlen)100 *f0865ec9SKyle Evans int rsa_import_simple_priv_key(rsa_priv_key *priv,
101 *f0865ec9SKyle Evans                                const u8 *n, u16 nlen, const u8 *d, u16 dlen,
102 *f0865ec9SKyle Evans 			       const u8 *p, u16 plen, const u8 *q, u16 qlen)
103 *f0865ec9SKyle Evans {
104 *f0865ec9SKyle Evans 	int ret;
105 *f0865ec9SKyle Evans 
106 *f0865ec9SKyle Evans 	MUST_HAVE((priv != NULL), ret, err);
107 *f0865ec9SKyle Evans 
108 *f0865ec9SKyle Evans 	MUST_HAVE(((p != NULL) && (q != NULL)) || ((p == NULL) && (q == NULL)), ret, err);
109 *f0865ec9SKyle Evans 
110 *f0865ec9SKyle Evans 	/* Import our big numbers */
111 *f0865ec9SKyle Evans 	if((p == NULL) || (q == NULL)){
112 *f0865ec9SKyle Evans 		priv->type = RSA_SIMPLE;
113 *f0865ec9SKyle Evans 		ret = nn_init_from_buf(&(priv->key.s.n), n, nlen); EG(ret, err);
114 *f0865ec9SKyle Evans 		ret = nn_init_from_buf(&(priv->key.s.d), d, dlen); EG(ret, err);
115 *f0865ec9SKyle Evans 	}
116 *f0865ec9SKyle Evans 	else{
117 *f0865ec9SKyle Evans 		priv->type = RSA_SIMPLE_PQ;
118 *f0865ec9SKyle Evans 		ret = nn_init_from_buf(&(priv->key.s_pq.n), n, nlen); EG(ret, err);
119 *f0865ec9SKyle Evans 		ret = nn_init_from_buf(&(priv->key.s_pq.d), d, dlen); EG(ret, err);
120 *f0865ec9SKyle Evans 		ret = nn_init_from_buf(&(priv->key.s_pq.p), p, plen); EG(ret, err);
121 *f0865ec9SKyle Evans 		ret = nn_init_from_buf(&(priv->key.s_pq.q), q, qlen); EG(ret, err);
122 *f0865ec9SKyle Evans 	}
123 *f0865ec9SKyle Evans 
124 *f0865ec9SKyle Evans err:
125 *f0865ec9SKyle Evans 	if(ret && (priv != NULL)){
126 *f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(priv, 0, sizeof(rsa_priv_key)));
127 *f0865ec9SKyle Evans 	}
128 *f0865ec9SKyle Evans 
129 *f0865ec9SKyle Evans 	return ret;
130 *f0865ec9SKyle Evans }
131 *f0865ec9SKyle Evans 
rsa_import_crt_priv_key(rsa_priv_key * priv,const u8 * p,u16 plen,const u8 * q,u16 qlen,const u8 * dP,u16 dPlen,const u8 * dQ,u16 dQlen,const u8 * qInv,u16 qInvlen,const u8 ** coeffs,u16 * coeffslens,u8 u)132 *f0865ec9SKyle Evans int rsa_import_crt_priv_key(rsa_priv_key *priv,
133 *f0865ec9SKyle Evans                             const u8 *p, u16 plen,
134 *f0865ec9SKyle Evans                             const u8 *q, u16 qlen,
135 *f0865ec9SKyle Evans                             const u8 *dP, u16 dPlen,
136 *f0865ec9SKyle Evans                             const u8 *dQ, u16 dQlen,
137 *f0865ec9SKyle Evans                             const u8 *qInv, u16 qInvlen,
138 *f0865ec9SKyle Evans                             const u8 **coeffs, u16 *coeffslens, u8 u)
139 *f0865ec9SKyle Evans {
140 *f0865ec9SKyle Evans 	int ret;
141 *f0865ec9SKyle Evans 
142 *f0865ec9SKyle Evans 	MUST_HAVE((priv != NULL), ret, err);
143 *f0865ec9SKyle Evans 
144 *f0865ec9SKyle Evans 	priv->type = RSA_CRT;
145 *f0865ec9SKyle Evans 	/* Import our big numbers */
146 *f0865ec9SKyle Evans 	ret = nn_init_from_buf(&(priv->key.crt.p), p, plen); EG(ret, err);
147 *f0865ec9SKyle Evans 	ret = nn_init_from_buf(&(priv->key.crt.q), q, qlen); EG(ret, err);
148 *f0865ec9SKyle Evans 	ret = nn_init_from_buf(&(priv->key.crt.dP), dP, dPlen); EG(ret, err);
149 *f0865ec9SKyle Evans 	ret = nn_init_from_buf(&(priv->key.crt.dQ), dQ, dQlen); EG(ret, err);
150 *f0865ec9SKyle Evans 	ret = nn_init_from_buf(&(priv->key.crt.qInv), qInv, qInvlen); EG(ret, err);
151 *f0865ec9SKyle Evans 
152 *f0865ec9SKyle Evans 	priv->key.crt.u = 0;
153 *f0865ec9SKyle Evans 
154 *f0865ec9SKyle Evans 	/* Import the optional coefficients if necessary */
155 *f0865ec9SKyle Evans 	if(coeffs != NULL){
156 *f0865ec9SKyle Evans 		unsigned int i;
157 *f0865ec9SKyle Evans 
158 *f0865ec9SKyle Evans 		MUST_HAVE((coeffslens != NULL), ret, err);
159 *f0865ec9SKyle Evans 		MUST_HAVE((u > 0) && (u < MAX_CRT_COEFFS), ret, err);
160 *f0865ec9SKyle Evans 
161 *f0865ec9SKyle Evans 		priv->key.crt.u = u;
162 *f0865ec9SKyle Evans 
163 *f0865ec9SKyle Evans 		for(i = 0; i < (3*u); i += 3){
164 *f0865ec9SKyle Evans 			rsa_priv_key_crt_coeffs *cur = &(priv->key.crt.coeffs[(i / 3)]);
165 *f0865ec9SKyle Evans 
166 *f0865ec9SKyle Evans 			ret = nn_init_from_buf(&(cur->r), coeffs[i],     coeffslens[i]);     EG(ret, err);
167 *f0865ec9SKyle Evans 			ret = nn_init_from_buf(&(cur->d), coeffs[i + 1], coeffslens[i + 1]); EG(ret, err);
168 *f0865ec9SKyle Evans 			ret = nn_init_from_buf(&(cur->t), coeffs[i + 2], coeffslens[i + 2]); EG(ret, err);
169 *f0865ec9SKyle Evans 		}
170 *f0865ec9SKyle Evans 	}
171 *f0865ec9SKyle Evans 
172 *f0865ec9SKyle Evans err:
173 *f0865ec9SKyle Evans 	if(ret && (priv != NULL)){
174 *f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(priv, 0, sizeof(rsa_priv_key)));
175 *f0865ec9SKyle Evans 	}
176 *f0865ec9SKyle Evans 	return ret;
177 *f0865ec9SKyle Evans }
178 *f0865ec9SKyle Evans 
179 *f0865ec9SKyle Evans /* I2OSP - Integer-to-Octet-String primitive
180 *f0865ec9SKyle Evans  * (as decribed in section 4.1 of RFC 8017)
181 *f0865ec9SKyle Evans  */
rsa_i2osp(nn_src_t x,u8 * buf,u32 buflen)182 *f0865ec9SKyle Evans int rsa_i2osp(nn_src_t x, u8 *buf, u32 buflen)
183 *f0865ec9SKyle Evans {
184 *f0865ec9SKyle Evans 	int ret;
185 *f0865ec9SKyle Evans 
186 *f0865ec9SKyle Evans 	/* Size check */
187 *f0865ec9SKyle Evans 	MUST_HAVE((buflen <= 0xffff), ret, err);
188 *f0865ec9SKyle Evans 	ret = _i2osp(x, buf, (u16)buflen);
189 *f0865ec9SKyle Evans 
190 *f0865ec9SKyle Evans err:
191 *f0865ec9SKyle Evans 	return ret;
192 *f0865ec9SKyle Evans }
193 *f0865ec9SKyle Evans 
194 *f0865ec9SKyle Evans /* OS2IP - Octet-String-to-Integer primitive
195 *f0865ec9SKyle Evans  * (as decribed in section 4.2 of RFC 8017)
196 *f0865ec9SKyle Evans  */
rsa_os2ip(nn_t x,const u8 * buf,u32 buflen)197 *f0865ec9SKyle Evans int rsa_os2ip(nn_t x, const u8 *buf, u32 buflen)
198 *f0865ec9SKyle Evans {
199 *f0865ec9SKyle Evans 	int ret;
200 *f0865ec9SKyle Evans 
201 *f0865ec9SKyle Evans 	/* Size check */
202 *f0865ec9SKyle Evans 	MUST_HAVE((buflen <= 0xffff), ret, err);
203 *f0865ec9SKyle Evans 	ret = _os2ip(x, buf, (u16)buflen);
204 *f0865ec9SKyle Evans 
205 *f0865ec9SKyle Evans err:
206 *f0865ec9SKyle Evans 	return ret;
207 *f0865ec9SKyle Evans }
208 *f0865ec9SKyle Evans 
209 *f0865ec9SKyle Evans /* The raw RSAEP function as defined in RFC 8017 section 5.1.1
210 *f0865ec9SKyle Evans  *     Input: an RSA public key and a big int message
211 *f0865ec9SKyle Evans  *     Output: a big int ciphertext
212 *f0865ec9SKyle Evans  *     Assumption:  RSA public key K is valid
213 *f0865ec9SKyle Evans  */
rsaep(const rsa_pub_key * pub,nn_src_t m,nn_t c)214 *f0865ec9SKyle Evans int rsaep(const rsa_pub_key *pub, nn_src_t m, nn_t c)
215 *f0865ec9SKyle Evans {
216 *f0865ec9SKyle Evans 	int ret, cmp;
217 *f0865ec9SKyle Evans 	nn_src_t n, e;
218 *f0865ec9SKyle Evans 
219 *f0865ec9SKyle Evans 	/* Sanity checks */
220 *f0865ec9SKyle Evans 	MUST_HAVE((pub != NULL), ret, err);
221 *f0865ec9SKyle Evans 
222 *f0865ec9SKyle Evans 	/* Make things more readable */
223 *f0865ec9SKyle Evans 	n = &(pub->n);
224 *f0865ec9SKyle Evans 	e = &(pub->e);
225 *f0865ec9SKyle Evans 
226 *f0865ec9SKyle Evans 	/* Sanity checks */
227 *f0865ec9SKyle Evans 	ret = nn_check_initialized(n); EG(ret, err);
228 *f0865ec9SKyle Evans 	ret = nn_check_initialized(e); EG(ret, err);
229 *f0865ec9SKyle Evans 
230 *f0865ec9SKyle Evans 	/* Check that m is indeed in [0, n-1], trigger an error if not */
231 *f0865ec9SKyle Evans 	MUST_HAVE((!nn_cmp(m, n, &cmp)) && (cmp < 0), ret, err);
232 *f0865ec9SKyle Evans 
233 *f0865ec9SKyle Evans 	/* Compute c = m^e mod n
234 *f0865ec9SKyle Evans 	 * NOTE: we use our internal *insecure* modular exponentation as we
235 *f0865ec9SKyle Evans 	 * are handling public key and data.
236 *f0865ec9SKyle Evans 	 */
237 *f0865ec9SKyle Evans 	ret = _nn_mod_pow_insecure(c, m, e, n);
238 *f0865ec9SKyle Evans 
239 *f0865ec9SKyle Evans err:
240 *f0865ec9SKyle Evans 	PTR_NULLIFY(n);
241 *f0865ec9SKyle Evans 	PTR_NULLIFY(e);
242 *f0865ec9SKyle Evans 
243 *f0865ec9SKyle Evans 	return ret;
244 *f0865ec9SKyle Evans }
245 *f0865ec9SKyle Evans 
246 *f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING
247 *f0865ec9SKyle Evans #define RSA_EXPONENT_BLINDING_SIZE 128
248 *f0865ec9SKyle Evans /*
249 *f0865ec9SKyle Evans  * Blind an exponent with a "small" multiple (of size "bits") of the input mod or (mod-1).
250 *f0865ec9SKyle Evans  * We use a relatively small multiple mainly because of potential big performance impacts on
251 *f0865ec9SKyle Evans  * modular exponentiation.
252 *f0865ec9SKyle Evans  */
_rsa_blind_exponent(nn_src_t e,nn_src_t mod,nn_t out,bitcnt_t bits,u8 dec)253 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsa_blind_exponent(nn_src_t e, nn_src_t mod, nn_t out, bitcnt_t bits, u8 dec)
254 *f0865ec9SKyle Evans {
255 *f0865ec9SKyle Evans 	int ret, check;
256 *f0865ec9SKyle Evans 	nn b;
257 *f0865ec9SKyle Evans 	b.magic = WORD(0);
258 *f0865ec9SKyle Evans 
259 *f0865ec9SKyle Evans 	ret = nn_init(&b, 0); EG(ret, err);
260 *f0865ec9SKyle Evans 	ret = nn_init(out, 0); EG(ret, err);
261 *f0865ec9SKyle Evans 
262 *f0865ec9SKyle Evans 	ret = nn_one(out); EG(ret, err);
263 *f0865ec9SKyle Evans 	ret = nn_lshift(out, out, bits); EG(ret, err);
264 *f0865ec9SKyle Evans 	ret = nn_iszero(out, &check); EG(ret, err);
265 *f0865ec9SKyle Evans 	/* Check for overflow */
266 *f0865ec9SKyle Evans 	MUST_HAVE(!check, ret, err);
267 *f0865ec9SKyle Evans 
268 *f0865ec9SKyle Evans 	/* Get a random value of "bits" count */
269 *f0865ec9SKyle Evans 	ret = nn_get_random_mod(&b, out); EG(ret, err);
270 *f0865ec9SKyle Evans 
271 *f0865ec9SKyle Evans 	if(dec){
272 *f0865ec9SKyle Evans 		ret = nn_copy(out, mod); EG(ret, err);
273 *f0865ec9SKyle Evans 		ret = nn_dec(out, out); EG(ret, err);
274 *f0865ec9SKyle Evans 		ret = nn_mul(&b, &b, out); EG(ret, err);
275 *f0865ec9SKyle Evans 	}
276 *f0865ec9SKyle Evans 	else{
277 *f0865ec9SKyle Evans 		ret = nn_mul(&b, &b, mod); EG(ret, err);
278 *f0865ec9SKyle Evans 	}
279 *f0865ec9SKyle Evans 
280 *f0865ec9SKyle Evans 	ret = nn_add(out, e, &b);
281 *f0865ec9SKyle Evans 
282 *f0865ec9SKyle Evans err:
283 *f0865ec9SKyle Evans 	nn_uninit(&b);
284 *f0865ec9SKyle Evans 
285 *f0865ec9SKyle Evans 	return ret;
286 *f0865ec9SKyle Evans }
287 *f0865ec9SKyle Evans #endif
288 *f0865ec9SKyle Evans 
289 *f0865ec9SKyle Evans /* The raw RSADP function as defined in RFC 8017 section 5.1.2
290 *f0865ec9SKyle Evans  *     Input: an RSA private key 'priv' and a big int ciphertext 'c'
291 *f0865ec9SKyle Evans  *     Output: a big int clear message 'm'
292 *f0865ec9SKyle Evans  *     Assumption:  RSA private key 'priv' is valid
293 *f0865ec9SKyle Evans  */
rsadp_crt_coeffs(const rsa_priv_key * priv,nn_src_t c,nn_t m,u8 u)294 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsadp_crt_coeffs(const rsa_priv_key *priv, nn_src_t c, nn_t m, u8 u)
295 *f0865ec9SKyle Evans {
296 *f0865ec9SKyle Evans 	int ret;
297 *f0865ec9SKyle Evans 	unsigned int i;
298 *f0865ec9SKyle Evans 	nn_src_t r_i, d_i, t_i, r_i_1;
299 *f0865ec9SKyle Evans 	nn m_i, h, R;
300 *f0865ec9SKyle Evans 	m_i.magic = h.magic = R.magic = WORD(0);
301 *f0865ec9SKyle Evans 
302 *f0865ec9SKyle Evans 	/* Sanity check on u */
303 *f0865ec9SKyle Evans 	MUST_HAVE((u < MAX_CRT_COEFFS), ret, err);
304 *f0865ec9SKyle Evans 
305 *f0865ec9SKyle Evans 	ret = nn_init(&m_i, 0); EG(ret, err);
306 *f0865ec9SKyle Evans 	ret = nn_init(&h, 0); EG(ret, err);
307 *f0865ec9SKyle Evans 	ret = nn_init(&R, 0); EG(ret, err);
308 *f0865ec9SKyle Evans 	/* NOTE: this is an internal function, sanity checks on priv and u have
309 *f0865ec9SKyle Evans 	 * been performed by the callers.
310 *f0865ec9SKyle Evans 	 */
311 *f0865ec9SKyle Evans 	/* R = r_1 */
312 *f0865ec9SKyle Evans 	ret = nn_copy(&R, &(priv->key.crt.coeffs[0].r)); EG(ret, err);
313 *f0865ec9SKyle Evans 	/* Loop  */
314 *f0865ec9SKyle Evans 	for(i = 1; i < u; i++){
315 *f0865ec9SKyle Evans 		r_i_1 = &(priv->key.crt.coeffs[i-1].r);
316 *f0865ec9SKyle Evans 		r_i = &(priv->key.crt.coeffs[i].r);
317 *f0865ec9SKyle Evans 		d_i = &(priv->key.crt.coeffs[i].d);
318 *f0865ec9SKyle Evans 		t_i = &(priv->key.crt.coeffs[i].t);
319 *f0865ec9SKyle Evans 
320 *f0865ec9SKyle Evans 		/* Sanity checks */
321 *f0865ec9SKyle Evans 		ret = nn_check_initialized(r_i_1); EG(ret, err);
322 *f0865ec9SKyle Evans 		ret = nn_check_initialized(r_i); EG(ret, err);
323 *f0865ec9SKyle Evans 		ret = nn_check_initialized(d_i); EG(ret, err);
324 *f0865ec9SKyle Evans 		ret = nn_check_initialized(t_i); EG(ret, err);
325 *f0865ec9SKyle Evans 
326 *f0865ec9SKyle Evans 		/* m_i = c^(d_i) mod r_i */
327 *f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING
328 *f0865ec9SKyle Evans 		ret = _rsa_blind_exponent(d_i, r_i, &h, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 1); EG(ret, err);
329 *f0865ec9SKyle Evans 		ret = nn_mod_pow(&m_i, c, &h, r_i); EG(ret, err);
330 *f0865ec9SKyle Evans #else
331 *f0865ec9SKyle Evans 		ret = nn_mod_pow(&m_i, c, d_i, r_i); EG(ret, err);
332 *f0865ec9SKyle Evans #endif
333 *f0865ec9SKyle Evans 		/* R = R * r_(i-1) */
334 *f0865ec9SKyle Evans 		ret = nn_mul(&R, &R, r_i_1); EG(ret, err);
335 *f0865ec9SKyle Evans 		/*  h = (m_i - m) * t_i mod r_i */
336 *f0865ec9SKyle Evans 		ret = nn_mod(&h, m, r_i); EG(ret, err);
337 *f0865ec9SKyle Evans 		ret = nn_mod_sub(&h, &m_i, &h, r_i); EG(ret, err);
338 *f0865ec9SKyle Evans 		ret = nn_mod_mul(&h, &h, t_i, r_i); EG(ret, err);
339 *f0865ec9SKyle Evans 		/* m = m + R * h */
340 *f0865ec9SKyle Evans 		ret = nn_mul(&h, &R, &h); EG(ret, err);
341 *f0865ec9SKyle Evans 		ret = nn_add(m, m, &h); EG(ret, err);
342 *f0865ec9SKyle Evans 	}
343 *f0865ec9SKyle Evans 
344 *f0865ec9SKyle Evans err:
345 *f0865ec9SKyle Evans 	nn_uninit(&m_i);
346 *f0865ec9SKyle Evans 	nn_uninit(&h);
347 *f0865ec9SKyle Evans 	nn_uninit(&R);
348 *f0865ec9SKyle Evans 
349 *f0865ec9SKyle Evans 	PTR_NULLIFY(r_i);
350 *f0865ec9SKyle Evans 	PTR_NULLIFY(d_i);
351 *f0865ec9SKyle Evans 	PTR_NULLIFY(t_i);
352 *f0865ec9SKyle Evans 	PTR_NULLIFY(r_i_1);
353 *f0865ec9SKyle Evans 
354 *f0865ec9SKyle Evans 	return ret;
355 *f0865ec9SKyle Evans }
356 *f0865ec9SKyle Evans 
rsadp_crt(const rsa_priv_key * priv,nn_src_t c,nn_t m)357 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsadp_crt(const rsa_priv_key *priv, nn_src_t c, nn_t m)
358 *f0865ec9SKyle Evans {
359 *f0865ec9SKyle Evans 	int ret;
360 *f0865ec9SKyle Evans 	nn_src_t p, q, dP, dQ, qInv;
361 *f0865ec9SKyle Evans 	nn m_1, m_2, h, msb_fixed;
362 *f0865ec9SKyle Evans 	u8 u;
363 *f0865ec9SKyle Evans 	m_1.magic = m_2.magic = h.magic = WORD(0);
364 *f0865ec9SKyle Evans 
365 *f0865ec9SKyle Evans 	ret = nn_init(&m_1, 0); EG(ret, err);
366 *f0865ec9SKyle Evans 	ret = nn_init(&m_2, 0); EG(ret, err);
367 *f0865ec9SKyle Evans 	ret = nn_init(&h, 0); EG(ret, err);
368 *f0865ec9SKyle Evans 	ret = nn_init(&msb_fixed, 0); EG(ret, err);
369 *f0865ec9SKyle Evans 
370 *f0865ec9SKyle Evans 	/* Make things more readable */
371 *f0865ec9SKyle Evans 	p    = &(priv->key.crt.p);
372 *f0865ec9SKyle Evans 	q    = &(priv->key.crt.q);
373 *f0865ec9SKyle Evans 	dP   = &(priv->key.crt.dP);
374 *f0865ec9SKyle Evans 	dQ   = &(priv->key.crt.dQ);
375 *f0865ec9SKyle Evans 	qInv = &(priv->key.crt.qInv);
376 *f0865ec9SKyle Evans 	u    = priv->key.crt.u;
377 *f0865ec9SKyle Evans 
378 *f0865ec9SKyle Evans 	/* Sanity checks */
379 *f0865ec9SKyle Evans 	ret = nn_check_initialized(p); EG(ret, err);
380 *f0865ec9SKyle Evans 	ret = nn_check_initialized(q); EG(ret, err);
381 *f0865ec9SKyle Evans 	ret = nn_check_initialized(dP); EG(ret, err);
382 *f0865ec9SKyle Evans 	ret = nn_check_initialized(dQ); EG(ret, err);
383 *f0865ec9SKyle Evans 	ret = nn_check_initialized(qInv); EG(ret, err);
384 *f0865ec9SKyle Evans 
385 *f0865ec9SKyle Evans 	/* m_1 = c^dP mod p */
386 *f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING
387 *f0865ec9SKyle Evans 	ret = _rsa_blind_exponent(dP, p, &h, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 1); EG(ret, err);
388 *f0865ec9SKyle Evans 	ret = nn_mod_pow(&m_1, c, &h, p); EG(ret, err);
389 *f0865ec9SKyle Evans #else
390 *f0865ec9SKyle Evans 	ret = nn_mod_pow(&m_1, c, dP, p); EG(ret, err);
391 *f0865ec9SKyle Evans #endif
392 *f0865ec9SKyle Evans 	/* m_2 = c^dQ mod q */
393 *f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING
394 *f0865ec9SKyle Evans 	ret = _rsa_blind_exponent(dQ, q, &h, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 1); EG(ret, err);
395 *f0865ec9SKyle Evans 	ret = nn_mod_pow(&m_2, c, &h, q); EG(ret, err);
396 *f0865ec9SKyle Evans #else
397 *f0865ec9SKyle Evans 	ret = nn_mod_pow(&m_2, c, dQ, q); EG(ret, err);
398 *f0865ec9SKyle Evans #endif
399 *f0865ec9SKyle Evans 	/* h = (m_1 - m_2) * qInv mod p */
400 *f0865ec9SKyle Evans 	ret = nn_mod(&h, &m_2, p); EG(ret, err);
401 *f0865ec9SKyle Evans 	ret = nn_mod_sub(&h, &m_1, &h, p); EG(ret, err);
402 *f0865ec9SKyle Evans 	ret = nn_mod_mul(&h, &h, qInv, p); EG(ret, err);
403 *f0865ec9SKyle Evans 	/* m = m_2 + q * h */
404 *f0865ec9SKyle Evans 	ret = nn_mul(m, &h, q); EG(ret, err);
405 *f0865ec9SKyle Evans 	ret = nn_add(m, &m_2, m); EG(ret, err);
406 *f0865ec9SKyle Evans 
407 *f0865ec9SKyle Evans 	if(u > 1){
408 *f0865ec9SKyle Evans 		ret = rsadp_crt_coeffs(priv, c, m, u);
409 *f0865ec9SKyle Evans 	}
410 *f0865ec9SKyle Evans 
411 *f0865ec9SKyle Evans err:
412 *f0865ec9SKyle Evans 	nn_uninit(&m_1);
413 *f0865ec9SKyle Evans 	nn_uninit(&m_2);
414 *f0865ec9SKyle Evans 	nn_uninit(&h);
415 *f0865ec9SKyle Evans 
416 *f0865ec9SKyle Evans 	PTR_NULLIFY(p);
417 *f0865ec9SKyle Evans 	PTR_NULLIFY(q);
418 *f0865ec9SKyle Evans 	PTR_NULLIFY(dP);
419 *f0865ec9SKyle Evans 	PTR_NULLIFY(dQ);
420 *f0865ec9SKyle Evans 	PTR_NULLIFY(qInv);
421 *f0865ec9SKyle Evans 
422 *f0865ec9SKyle Evans 	return ret;
423 *f0865ec9SKyle Evans }
424 *f0865ec9SKyle Evans 
rsadp_nocrt(const rsa_priv_key * priv,nn_src_t c,nn_t m)425 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsadp_nocrt(const rsa_priv_key *priv, nn_src_t c, nn_t m)
426 *f0865ec9SKyle Evans {
427 *f0865ec9SKyle Evans 	int ret, cmp;
428 *f0865ec9SKyle Evans 	nn_src_t n, d, p, q;
429 *f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING
430 *f0865ec9SKyle Evans 	nn b1, b2;
431 *f0865ec9SKyle Evans 	b1.magic = b2.magic = WORD(0);
432 *f0865ec9SKyle Evans #endif
433 *f0865ec9SKyle Evans 	/* Make things more readable */
434 *f0865ec9SKyle Evans 	if(priv->type == RSA_SIMPLE){
435 *f0865ec9SKyle Evans 		n = &(priv->key.s.n);
436 *f0865ec9SKyle Evans 		d = &(priv->key.s.d);
437 *f0865ec9SKyle Evans 	}
438 *f0865ec9SKyle Evans 	else if(priv->type == RSA_SIMPLE_PQ){
439 *f0865ec9SKyle Evans 		n = &(priv->key.s_pq.n);
440 *f0865ec9SKyle Evans 		d = &(priv->key.s_pq.d);
441 *f0865ec9SKyle Evans 	}
442 *f0865ec9SKyle Evans 	else{
443 *f0865ec9SKyle Evans 		ret = -1;
444 *f0865ec9SKyle Evans 		goto err;
445 *f0865ec9SKyle Evans 	}
446 *f0865ec9SKyle Evans 	/* Sanity checks */
447 *f0865ec9SKyle Evans 	ret = nn_check_initialized(n); EG(ret, err);
448 *f0865ec9SKyle Evans 	ret = nn_check_initialized(d); EG(ret, err);
449 *f0865ec9SKyle Evans 	/* Check that c is indeed in [0, n-1], trigger an error if not */
450 *f0865ec9SKyle Evans 	MUST_HAVE((!nn_cmp(c, n, &cmp)) && (cmp < 0), ret, err);
451 *f0865ec9SKyle Evans 
452 *f0865ec9SKyle Evans 	/* Compute m = c^d mod n */
453 *f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING
454 *f0865ec9SKyle Evans 	/* When we are asked to use exponent blinding, we MUST have a RSA_SIMPLE_PQ
455 *f0865ec9SKyle Evans 	 * type key in order to be able to compute our Phi(n) = (p-1)(q-1) and perform
456 *f0865ec9SKyle Evans 	 * the blinding.
457 *f0865ec9SKyle Evans 	 */
458 *f0865ec9SKyle Evans 	if(priv->type == RSA_SIMPLE_PQ){
459 *f0865ec9SKyle Evans 		p = &(priv->key.s_pq.p);
460 *f0865ec9SKyle Evans 		q = &(priv->key.s_pq.q);
461 *f0865ec9SKyle Evans 		ret = nn_init(&b1, 0); EG(ret, err);
462 *f0865ec9SKyle Evans 		ret = nn_init(&b2, 0); EG(ret, err);
463 *f0865ec9SKyle Evans 		ret = nn_dec(&b1, p); EG(ret, err);
464 *f0865ec9SKyle Evans 		ret = nn_dec(&b2, q); EG(ret, err);
465 *f0865ec9SKyle Evans 		ret = nn_mul(&b1, &b1, &b2); EG(ret, err);
466 *f0865ec9SKyle Evans 		ret = _rsa_blind_exponent(d, &b1, &b2, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 0); EG(ret, err);
467 *f0865ec9SKyle Evans 		ret = nn_mod_pow(m, c, &b2, n); EG(ret, err);
468 *f0865ec9SKyle Evans 	}
469 *f0865ec9SKyle Evans 	else{
470 *f0865ec9SKyle Evans 		ret = -1;
471 *f0865ec9SKyle Evans 		goto err;
472 *f0865ec9SKyle Evans 	}
473 *f0865ec9SKyle Evans #else
474 *f0865ec9SKyle Evans 	FORCE_USED_VAR(p);
475 *f0865ec9SKyle Evans 	FORCE_USED_VAR(q);
476 *f0865ec9SKyle Evans 	ret = nn_mod_pow(m, c, d, n);
477 *f0865ec9SKyle Evans #endif
478 *f0865ec9SKyle Evans 
479 *f0865ec9SKyle Evans err:
480 *f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING
481 *f0865ec9SKyle Evans 	nn_uninit(&b1);
482 *f0865ec9SKyle Evans 	nn_uninit(&b2);
483 *f0865ec9SKyle Evans #endif
484 *f0865ec9SKyle Evans 	PTR_NULLIFY(n);
485 *f0865ec9SKyle Evans 	PTR_NULLIFY(d);
486 *f0865ec9SKyle Evans 	PTR_NULLIFY(p);
487 *f0865ec9SKyle Evans 	PTR_NULLIFY(q);
488 *f0865ec9SKyle Evans 
489 *f0865ec9SKyle Evans 	return ret;
490 *f0865ec9SKyle Evans }
491 *f0865ec9SKyle Evans 
rsadp(const rsa_priv_key * priv,nn_src_t c,nn_t m)492 *f0865ec9SKyle Evans int rsadp(const rsa_priv_key *priv, nn_src_t c, nn_t m)
493 *f0865ec9SKyle Evans {
494 *f0865ec9SKyle Evans 	int ret;
495 *f0865ec9SKyle Evans 
496 *f0865ec9SKyle Evans 	/* Sanity checks */
497 *f0865ec9SKyle Evans 	MUST_HAVE((priv != NULL), ret, err);
498 *f0865ec9SKyle Evans 
499 *f0865ec9SKyle Evans 	/* Do we have a simple or a CRT key? */
500 *f0865ec9SKyle Evans 	if((priv->type == RSA_SIMPLE) || (priv->type == RSA_SIMPLE_PQ)){
501 *f0865ec9SKyle Evans 		ret = rsadp_nocrt(priv, c, m); EG(ret, err);
502 *f0865ec9SKyle Evans 	}
503 *f0865ec9SKyle Evans 	else if(priv->type == RSA_CRT){
504 *f0865ec9SKyle Evans 		ret = rsadp_crt(priv, c, m); EG(ret, err);
505 *f0865ec9SKyle Evans 	}
506 *f0865ec9SKyle Evans 	else{
507 *f0865ec9SKyle Evans 		ret = -1;
508 *f0865ec9SKyle Evans 		goto err;
509 *f0865ec9SKyle Evans 	}
510 *f0865ec9SKyle Evans 
511 *f0865ec9SKyle Evans err:
512 *f0865ec9SKyle Evans 	return ret;
513 *f0865ec9SKyle Evans }
514 *f0865ec9SKyle Evans 
515 *f0865ec9SKyle Evans /*
516 *f0865ec9SKyle Evans  * The "hardened" version of rsadp that uses message blinding as well
517 *f0865ec9SKyle Evans  * as output check for Bellcore style fault attacks.
518 *f0865ec9SKyle Evans  *
519 *f0865ec9SKyle Evans  */
rsadp_hardened(const rsa_priv_key * priv,const rsa_pub_key * pub,nn_src_t c,nn_t m)520 *f0865ec9SKyle Evans int rsadp_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, nn_src_t c, nn_t m)
521 *f0865ec9SKyle Evans {
522 *f0865ec9SKyle Evans 	int ret, check;
523 *f0865ec9SKyle Evans 	nn_src_t n, e;
524 *f0865ec9SKyle Evans 	nn b, binv;
525 *f0865ec9SKyle Evans 	b.magic = binv.magic = WORD(0);
526 *f0865ec9SKyle Evans 
527 *f0865ec9SKyle Evans 	/* Make things more readable */
528 *f0865ec9SKyle Evans 	n = &(pub->n);
529 *f0865ec9SKyle Evans 	e = &(pub->e);
530 *f0865ec9SKyle Evans 
531 *f0865ec9SKyle Evans 	/* Sanity checks */
532 *f0865ec9SKyle Evans 	MUST_HAVE((priv != NULL) && (pub != NULL), ret, err);
533 *f0865ec9SKyle Evans 
534 *f0865ec9SKyle Evans 	/* Blind the message: get a random value for b prime with n
535 *f0865ec9SKyle Evans 	 * and compute its modular inverse.
536 *f0865ec9SKyle Evans 	 */
537 *f0865ec9SKyle Evans 	ret = nn_init(&b, 0); EG(ret, err);
538 *f0865ec9SKyle Evans 	ret = nn_init(&binv, 0); EG(ret, err);
539 *f0865ec9SKyle Evans 	ret = -1;
540 *f0865ec9SKyle Evans 	while(ret){
541 *f0865ec9SKyle Evans 		ret = nn_get_random_mod(&b, n); EG(ret, err);
542 *f0865ec9SKyle Evans 		ret = nn_modinv(&binv, &b, n);
543 *f0865ec9SKyle Evans 	}
544 *f0865ec9SKyle Evans 	/* Exponentiate the blinder to the public value */
545 *f0865ec9SKyle Evans 	ret = _nn_mod_pow_insecure(m, &b, e, n); EG(ret, err);
546 *f0865ec9SKyle Evans 	/* Perform message blinding */
547 *f0865ec9SKyle Evans 	ret = nn_mod_mul(&b, m, c, n); EG(ret, err);
548 *f0865ec9SKyle Evans 
549 *f0865ec9SKyle Evans 	/* Perform rsadp on the blinded message */
550 *f0865ec9SKyle Evans 	ret = rsadp(priv, &b, m); EG(ret, err);
551 *f0865ec9SKyle Evans 
552 *f0865ec9SKyle Evans 	/* Unblind the result */
553 *f0865ec9SKyle Evans 	ret = nn_mod_mul(m, m, &binv, n); EG(ret, err);
554 *f0865ec9SKyle Evans 
555 *f0865ec9SKyle Evans 	/* Now perform the public operation to check the result.
556 *f0865ec9SKyle Evans 	 * This is useful against some fault attacks (Bellcore style).
557 *f0865ec9SKyle Evans 	 */
558 *f0865ec9SKyle Evans 	ret = rsaep(pub, m, &b); EG(ret, err);
559 *f0865ec9SKyle Evans 	ret = nn_cmp(c, &b, &check); EG(ret, err);
560 *f0865ec9SKyle Evans 	MUST_HAVE((check == 0), ret, err);
561 *f0865ec9SKyle Evans 
562 *f0865ec9SKyle Evans err:
563 *f0865ec9SKyle Evans 	nn_uninit(&b);
564 *f0865ec9SKyle Evans 	nn_uninit(&binv);
565 *f0865ec9SKyle Evans 
566 *f0865ec9SKyle Evans 	PTR_NULLIFY(n);
567 *f0865ec9SKyle Evans 	PTR_NULLIFY(e);
568 *f0865ec9SKyle Evans 
569 *f0865ec9SKyle Evans 	return ret;
570 *f0865ec9SKyle Evans }
571 *f0865ec9SKyle Evans 
572 *f0865ec9SKyle Evans /* The raw RSASP1 function as defined in RFC 8017 section 5.2.1
573 *f0865ec9SKyle Evans  *     Input: an RSA private key 'priv' and a big int message 'm'
574 *f0865ec9SKyle Evans  *     Output: a big int signature 's'
575 *f0865ec9SKyle Evans  *     Assumption:  RSA private key 'priv' is valid
576 *f0865ec9SKyle Evans  */
rsasp1(const rsa_priv_key * priv,nn_src_t m,nn_t s)577 *f0865ec9SKyle Evans int rsasp1(const rsa_priv_key *priv, nn_src_t m, nn_t s)
578 *f0865ec9SKyle Evans {
579 *f0865ec9SKyle Evans 	return rsadp(priv, m, s);
580 *f0865ec9SKyle Evans }
581 *f0865ec9SKyle Evans 
582 *f0865ec9SKyle Evans /*
583 *f0865ec9SKyle Evans  * The "hardened" version of rsasp1 that uses message blinding as well
584 *f0865ec9SKyle Evans  * as optional exponent blinding.
585 *f0865ec9SKyle Evans  *
586 *f0865ec9SKyle Evans  */
rsasp1_hardened(const rsa_priv_key * priv,const rsa_pub_key * pub,nn_src_t m,nn_t s)587 *f0865ec9SKyle Evans int rsasp1_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, nn_src_t m, nn_t s)
588 *f0865ec9SKyle Evans {
589 *f0865ec9SKyle Evans 	return rsadp_hardened(priv, pub, m, s);
590 *f0865ec9SKyle Evans }
591 *f0865ec9SKyle Evans 
592 *f0865ec9SKyle Evans 
593 *f0865ec9SKyle Evans /* The raw RSAVP1 function as defined in RFC 8017 section 5.2.2
594 *f0865ec9SKyle Evans  *     Input: an RSA public key 'pub' and a big int signature 's'
595 *f0865ec9SKyle Evans  *     Output: a big int ciphertext 'm'
596 *f0865ec9SKyle Evans  *     Assumption:  RSA public key 'pub' is valid
597 *f0865ec9SKyle Evans  */
rsavp1(const rsa_pub_key * pub,nn_src_t s,nn_t m)598 *f0865ec9SKyle Evans int rsavp1(const rsa_pub_key *pub, nn_src_t s, nn_t m)
599 *f0865ec9SKyle Evans {
600 *f0865ec9SKyle Evans 	return rsaep(pub, s, m);
601 *f0865ec9SKyle Evans }
602 *f0865ec9SKyle Evans 
rsa_digestinfo_from_hash(gen_hash_alg_type gen_hash_type,u8 * digestinfo,u32 * digestinfo_len)603 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsa_digestinfo_from_hash(gen_hash_alg_type gen_hash_type, u8 *digestinfo, u32 *digestinfo_len)
604 *f0865ec9SKyle Evans {
605 *f0865ec9SKyle Evans 	int ret;
606 *f0865ec9SKyle Evans 
607 *f0865ec9SKyle Evans 	/* Sanity check */
608 *f0865ec9SKyle Evans 	MUST_HAVE((digestinfo_len != NULL), ret, err);
609 *f0865ec9SKyle Evans 
610 *f0865ec9SKyle Evans 	switch(gen_hash_type){
611 *f0865ec9SKyle Evans 		case HASH_MD2:{
612 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a,
613 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02,
614 *f0865ec9SKyle Evans 						   0x05, 0x00, 0x04, 0x10 };
615 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
616 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
617 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
618 *f0865ec9SKyle Evans 			break;
619 *f0865ec9SKyle Evans 		}
620 *f0865ec9SKyle Evans 		case HASH_MD4:{
621 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a,
622 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04,
623 *f0865ec9SKyle Evans 						   0x05, 0x00, 0x04, 0x10 };
624 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
625 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
626 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
627 *f0865ec9SKyle Evans 			break;
628 *f0865ec9SKyle Evans 		}
629 *f0865ec9SKyle Evans 		case HASH_MD5:{
630 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a,
631 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05,
632 *f0865ec9SKyle Evans 						   0x05, 0x00, 0x04, 0x10 };
633 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
634 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
635 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
636 *f0865ec9SKyle Evans 			break;
637 *f0865ec9SKyle Evans 		}
638 *f0865ec9SKyle Evans 		case HASH_SHA0:{
639 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
640 *f0865ec9SKyle Evans 						   0x0e, 0x03, 0x02, 0x12, 0x05, 0x00, 0x04,
641 *f0865ec9SKyle Evans 						   0x14 };
642 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
643 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
644 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
645 *f0865ec9SKyle Evans 			break;
646 *f0865ec9SKyle Evans 		}
647 *f0865ec9SKyle Evans 		case HASH_SHA1:{
648 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
649 *f0865ec9SKyle Evans 						   0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04,
650 *f0865ec9SKyle Evans 						   0x14 };
651 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
652 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
653 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
654 *f0865ec9SKyle Evans 			break;
655 *f0865ec9SKyle Evans 		}
656 *f0865ec9SKyle Evans 		case HASH_SHA224:{
657 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60,
658 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
659 *f0865ec9SKyle Evans 						   0x04, 0x05, 0x00, 0x04, 0x1c };
660 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
661 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
662 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
663 *f0865ec9SKyle Evans 			break;
664 *f0865ec9SKyle Evans 		}
665 *f0865ec9SKyle Evans 		case HASH_SHA256:{
666 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
667 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
668 *f0865ec9SKyle Evans 						   0x01, 0x05, 0x00, 0x04, 0x20 };
669 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
670 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
671 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
672 *f0865ec9SKyle Evans 			break;
673 *f0865ec9SKyle Evans 		}
674 *f0865ec9SKyle Evans 		case HASH_SHA384:{
675 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60,
676 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
677 *f0865ec9SKyle Evans 						   0x02, 0x05, 0x00, 0x04, 0x30 };
678 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
679 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
680 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
681 *f0865ec9SKyle Evans 			break;
682 *f0865ec9SKyle Evans 		}
683 *f0865ec9SKyle Evans 		case HASH_SHA512:{
684 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60,
685 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
686 *f0865ec9SKyle Evans 						   0x03, 0x05, 0x00, 0x04, 0x40 };
687 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
688 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
689 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
690 *f0865ec9SKyle Evans 			break;
691 *f0865ec9SKyle Evans 		}
692 *f0865ec9SKyle Evans 		case HASH_SHA512_224:{
693 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60,
694 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
695 *f0865ec9SKyle Evans 						   0x05, 0x05, 0x00, 0x04, 0x1c };
696 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
697 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
698 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
699 *f0865ec9SKyle Evans 			break;
700 *f0865ec9SKyle Evans 		}
701 *f0865ec9SKyle Evans 		case HASH_SHA512_256:{
702 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
703 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
704 *f0865ec9SKyle Evans 						   0x06, 0x05, 0x00, 0x04, 0x20 };
705 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
706 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
707 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
708 *f0865ec9SKyle Evans 			break;
709 *f0865ec9SKyle Evans 		}
710 *f0865ec9SKyle Evans 		case HASH_RIPEMD160:{
711 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
712 *f0865ec9SKyle Evans 						   0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04,
713 *f0865ec9SKyle Evans 						   0x14 };
714 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
715 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
716 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
717 *f0865ec9SKyle Evans 			break;
718 *f0865ec9SKyle Evans 		}
719 *f0865ec9SKyle Evans 		/* The following SHA-3 oids have been taken from
720 *f0865ec9SKyle Evans 		 *     https://www.ietf.org/archive/id/draft-jivsov-openpgp-sha3-01.txt
721 *f0865ec9SKyle Evans 		 *
722 *f0865ec9SKyle Evans 		 * The specific case of SHA3-224 is infered from the OID of SHA3-224 although
723 *f0865ec9SKyle Evans 		 * not standardized.
724 *f0865ec9SKyle Evans 		 */
725 *f0865ec9SKyle Evans 		case HASH_SHA3_224:{
726 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60,
727 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
728 *f0865ec9SKyle Evans 						   0x07, 0x05, 0x00, 0x04, 0x1c };
729 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
730 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
731 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
732 *f0865ec9SKyle Evans 			break;
733 *f0865ec9SKyle Evans 		}
734 *f0865ec9SKyle Evans 		case HASH_SHA3_256:{
735 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
736 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
737 *f0865ec9SKyle Evans 						   0x08, 0x05, 0x00, 0x04, 0x20 };
738 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
739 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
740 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
741 *f0865ec9SKyle Evans 			break;
742 *f0865ec9SKyle Evans 		}
743 *f0865ec9SKyle Evans 		case HASH_SHA3_384:{
744 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60,
745 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
746 *f0865ec9SKyle Evans 						   0x09, 0x05, 0x00, 0x04, 0x30 };
747 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
748 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
749 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
750 *f0865ec9SKyle Evans 			break;
751 *f0865ec9SKyle Evans 		}
752 *f0865ec9SKyle Evans 		case HASH_SHA3_512:{
753 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60,
754 *f0865ec9SKyle Evans 						   0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
755 *f0865ec9SKyle Evans 						   0x0a ,0x05, 0x00, 0x04, 0x40 };
756 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
757 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
758 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
759 *f0865ec9SKyle Evans 			break;
760 *f0865ec9SKyle Evans 		}
761 *f0865ec9SKyle Evans 		/* For SM3, the "RSA Signing with SM3" OID is taken from:
762 *f0865ec9SKyle Evans 		 *     http://gmssl.org/docs/oid.html
763 *f0865ec9SKyle Evans 		 */
764 *f0865ec9SKyle Evans 		case HASH_SM3:{
765 *f0865ec9SKyle Evans 			const u8 _digestinfo[] = { 0x30, 0x30, 0x30, 0x0d, 0x06, 0x08, 0x2A,
766 *f0865ec9SKyle Evans 						   0x81, 0x1c, 0xcf, 0x55, 0x01, 0x83, 0x78,
767 *f0865ec9SKyle Evans 						   0x05, 0x00, 0x04, 0x20 };
768 *f0865ec9SKyle Evans 			MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err);
769 *f0865ec9SKyle Evans 			ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err);
770 *f0865ec9SKyle Evans 			(*digestinfo_len) = sizeof(_digestinfo);
771 *f0865ec9SKyle Evans 			break;
772 *f0865ec9SKyle Evans 		}
773 *f0865ec9SKyle Evans 		default:{
774 *f0865ec9SKyle Evans 			ret = -1;
775 *f0865ec9SKyle Evans 			goto err;
776 *f0865ec9SKyle Evans 		}
777 *f0865ec9SKyle Evans 	}
778 *f0865ec9SKyle Evans 
779 *f0865ec9SKyle Evans err:
780 *f0865ec9SKyle Evans 	return ret;
781 *f0865ec9SKyle Evans }
782 *f0865ec9SKyle Evans 
783 *f0865ec9SKyle Evans /* GF1 as a mask generation function as described in RFC 8017 Appendix B.2.1
784 *f0865ec9SKyle Evans  *     z is the 'seed', and zlen its length
785 *f0865ec9SKyle Evans  */
_mgf1(const u8 * z,u16 zlen,u8 * mask,u64 masklen,gen_hash_alg_type mgf_hash_type)786 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _mgf1(const u8 *z, u16 zlen,
787 *f0865ec9SKyle Evans 					   u8 *mask, u64 masklen,
788 *f0865ec9SKyle Evans 					   gen_hash_alg_type mgf_hash_type)
789 *f0865ec9SKyle Evans {
790 *f0865ec9SKyle Evans 	int ret;
791 *f0865ec9SKyle Evans 	u8 hlen, block_size;
792 *f0865ec9SKyle Evans 	u32 c, ceil;
793 *f0865ec9SKyle Evans 	u8 C[4];
794 *f0865ec9SKyle Evans 	const u8 *input[3] = { z, C, NULL };
795 *f0865ec9SKyle Evans 	u32 ilens[3] = { zlen, 4, 0 };
796 *f0865ec9SKyle Evans 	u8 digest[MAX_DIGEST_SIZE];
797 *f0865ec9SKyle Evans 
798 *f0865ec9SKyle Evans 	/* Zeroize local variables */
799 *f0865ec9SKyle Evans 	ret = local_memset(C, 0, sizeof(C)); EG(ret, err);
800 *f0865ec9SKyle Evans 	ret = local_memset(digest, 0, sizeof(digest)); EG(ret, err);
801 *f0865ec9SKyle Evans 
802 *f0865ec9SKyle Evans 	/* Sanity checks */
803 *f0865ec9SKyle Evans 	MUST_HAVE((z != NULL) && (mask != NULL), ret, err);
804 *f0865ec9SKyle Evans 
805 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(mgf_hash_type, &hlen, &block_size); EG(ret, err);
806 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
807 *f0865ec9SKyle Evans 
808 *f0865ec9SKyle Evans 	/* masklen must be < 2**32 * hlen */
809 *f0865ec9SKyle Evans 	MUST_HAVE((masklen < ((u64)hlen * ((u64)0x1 << 32))), ret, err);
810 *f0865ec9SKyle Evans 	ceil = (u32)(masklen / hlen) + !!(masklen % hlen);
811 *f0865ec9SKyle Evans 
812 *f0865ec9SKyle Evans 	for(c = 0; c < ceil; c++){
813 *f0865ec9SKyle Evans 		/* 3.A: C = I2OSP (counter, 4) */
814 *f0865ec9SKyle Evans 		C[0] = (u8)((c >> 24) & 0xff);
815 *f0865ec9SKyle Evans 		C[1] = (u8)((c >> 16) & 0xff);
816 *f0865ec9SKyle Evans 		C[2] = (u8)((c >>  8) & 0xff);
817 *f0865ec9SKyle Evans 		C[3] = (u8)((c >>  0) & 0xff);
818 *f0865ec9SKyle Evans 
819 *f0865ec9SKyle Evans 		/* 3.B + 4. */
820 *f0865ec9SKyle Evans 		if ((masklen % hlen) && (c == (ceil - 1))) { /* need last chunk smaller than hlen */
821 *f0865ec9SKyle Evans 			ret = gen_hash_hfunc_scattered(input, ilens, digest, mgf_hash_type); EG(ret, err);
822 *f0865ec9SKyle Evans 			ret = local_memcpy(&mask[c * hlen], digest, (u32)(masklen % hlen)); EG(ret, err);
823 *f0865ec9SKyle Evans 		} else {                                     /* common case, i.e. complete chunk */
824 *f0865ec9SKyle Evans 			ret = gen_hash_hfunc_scattered(input, ilens, &mask[c * hlen], mgf_hash_type); EG(ret, err);
825 *f0865ec9SKyle Evans 		}
826 *f0865ec9SKyle Evans 	}
827 *f0865ec9SKyle Evans err:
828 *f0865ec9SKyle Evans 	return ret;
829 *f0865ec9SKyle Evans }
830 *f0865ec9SKyle Evans 
831 *f0865ec9SKyle Evans /* EMSA-PSS-ENCODE encoding as described in RFC 8017 section 9.1.1
832 *f0865ec9SKyle Evans  * NOTE: we enforce MGF1 as a mask generation function
833 *f0865ec9SKyle Evans  */
emsa_pss_encode(const u8 * m,u32 mlen,u8 * em,u32 embits,u16 * eminlen,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type,u32 saltlen,const u8 * forced_salt)834 *f0865ec9SKyle Evans int emsa_pss_encode(const u8 *m, u32 mlen, u8 *em, u32 embits,
835 *f0865ec9SKyle Evans                     u16 *eminlen, gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type,
836 *f0865ec9SKyle Evans                     u32 saltlen, const u8 *forced_salt)
837 *f0865ec9SKyle Evans {
838 *f0865ec9SKyle Evans 	int ret;
839 *f0865ec9SKyle Evans 	u8 hlen, block_size;
840 *f0865ec9SKyle Evans 	u8 mhash[MAX_DIGEST_SIZE];
841 *f0865ec9SKyle Evans 	u8 h[MAX_DIGEST_SIZE];
842 *f0865ec9SKyle Evans 	u8 zeroes[8];
843 *f0865ec9SKyle Evans 	/* Reasonable sizes:
844 *f0865ec9SKyle Evans 	 * NOTE: for the cases where the salt exceeds this size, we return an error
845 *f0865ec9SKyle Evans 	 * alhough this should not happen if our underlying libecc supports the current
846 *f0865ec9SKyle Evans 	 * modulus size.
847 *f0865ec9SKyle Evans 	 */
848 *f0865ec9SKyle Evans 	u8 salt[NN_USABLE_MAX_BYTE_LEN];
849 *f0865ec9SKyle Evans 	u8 *dbmask = em;
850 *f0865ec9SKyle Evans 	const u8 *input[2] = { m, NULL };
851 *f0865ec9SKyle Evans 	u32 ilens[2] = { mlen, 0 };
852 *f0865ec9SKyle Evans 	u32 emlen, dblen, pslen;
853 *f0865ec9SKyle Evans 	unsigned int i;
854 *f0865ec9SKyle Evans 	u8 mask;
855 *f0865ec9SKyle Evans 	const u8 *input_[4] = { zeroes, mhash, salt, NULL };
856 *f0865ec9SKyle Evans 	u32 ilens_[4];
857 *f0865ec9SKyle Evans 
858 *f0865ec9SKyle Evans 	/* Zeroize local variables */
859 *f0865ec9SKyle Evans 	ret = local_memset(mhash, 0, sizeof(mhash)); EG(ret, err);
860 *f0865ec9SKyle Evans 	ret = local_memset(h, 0, sizeof(h)); EG(ret, err);
861 *f0865ec9SKyle Evans 	ret = local_memset(salt, 0, sizeof(salt)); EG(ret, err);
862 *f0865ec9SKyle Evans 	ret = local_memset(zeroes, 0, sizeof(zeroes)); EG(ret, err);
863 *f0865ec9SKyle Evans 	ret = local_memset(ilens_, 0, sizeof(ilens_)); EG(ret, err);
864 *f0865ec9SKyle Evans 
865 *f0865ec9SKyle Evans 	/* Sanity checks */
866 *f0865ec9SKyle Evans 	MUST_HAVE((m != NULL) && (em != NULL) && (eminlen != NULL), ret, err);
867 *f0865ec9SKyle Evans 
868 *f0865ec9SKyle Evans 	/* We only allow salt up to a certain size */
869 *f0865ec9SKyle Evans 	MUST_HAVE((saltlen <= sizeof(salt)), ret, err);
870 *f0865ec9SKyle Evans 	emlen = BYTECEIL(embits);
871 *f0865ec9SKyle Evans 	MUST_HAVE((emlen < (u32)((u32)0x1 << 16)), ret, err);
872 *f0865ec9SKyle Evans 
873 *f0865ec9SKyle Evans 	/* Check that we have enough room for the output */
874 *f0865ec9SKyle Evans 	MUST_HAVE(((*eminlen) >= emlen), ret, err);
875 *f0865ec9SKyle Evans 
876 *f0865ec9SKyle Evans 	/* Get the used hash information */
877 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err);
878 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
879 *f0865ec9SKyle Evans 
880 *f0865ec9SKyle Evans 	/* emBits at least 8hLen + 8sLen + 9 */
881 *f0865ec9SKyle Evans 	MUST_HAVE((embits >= ((8*(u32)hlen) + (8*(u32)saltlen) + 9)), ret, err);
882 *f0865ec9SKyle Evans 
883 *f0865ec9SKyle Evans 	/*  If emLen < hLen + sLen + 2, output "encoding error" and stop. */
884 *f0865ec9SKyle Evans 	MUST_HAVE((emlen >= ((u32)hlen + (u32)saltlen + 2)), ret, err);
885 *f0865ec9SKyle Evans 
886 *f0865ec9SKyle Evans 	/* mHash = Hash(M) */
887 *f0865ec9SKyle Evans 	ret = gen_hash_hfunc_scattered(input, ilens, mhash, gen_hash_type); EG(ret, err);
888 *f0865ec9SKyle Evans 
889 *f0865ec9SKyle Evans 	/*  Generate a random octet string salt of length sLen; if sLen = 0
890 *f0865ec9SKyle Evans 	 *  then salt is the empty string.
891 *f0865ec9SKyle Evans 	 *  M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
892 *f0865ec9SKyle Evans 	 *  H = Hash(M'),
893 *f0865ec9SKyle Evans 	 */
894 *f0865ec9SKyle Evans 	if(forced_salt != NULL){
895 *f0865ec9SKyle Evans 		/* We are given a forced salt, use it */
896 *f0865ec9SKyle Evans 		ret = local_memcpy(salt, forced_salt, saltlen); EG(ret, err);
897 *f0865ec9SKyle Evans 	}
898 *f0865ec9SKyle Evans 	else{
899 *f0865ec9SKyle Evans 		/* We only support generating salts of size <= 2**16 */
900 *f0865ec9SKyle Evans 		MUST_HAVE((saltlen <= 0xffff), ret, err);
901 *f0865ec9SKyle Evans 		/* Get random salt */
902 *f0865ec9SKyle Evans 		ret = get_random(salt, (u16)saltlen); EG(ret, err);
903 *f0865ec9SKyle Evans 	}
904 *f0865ec9SKyle Evans 	ilens_[0] = sizeof(zeroes);
905 *f0865ec9SKyle Evans 	ilens_[1] = hlen;
906 *f0865ec9SKyle Evans 	ilens_[2] = saltlen;
907 *f0865ec9SKyle Evans 	ilens_[3] = 0;
908 *f0865ec9SKyle Evans 	ret = gen_hash_hfunc_scattered(input_, ilens_, h, gen_hash_type); EG(ret, err);
909 *f0865ec9SKyle Evans 
910 *f0865ec9SKyle Evans 	/* dbMask = MGF(H, emLen - hLen - 1)
911 *f0865ec9SKyle Evans 	 * NOTE: dbmask points to &em[0]
912 *f0865ec9SKyle Evans 	 */
913 *f0865ec9SKyle Evans 	dblen = (emlen - hlen - 1);
914 *f0865ec9SKyle Evans 	pslen = (dblen - saltlen - 1); /* padding string PS len */
915 *f0865ec9SKyle Evans 	ret = _mgf1(h, hlen, dbmask, dblen, mgf_hash_type); EG(ret, err);
916 *f0865ec9SKyle Evans 
917 *f0865ec9SKyle Evans         /*
918 *f0865ec9SKyle Evans          * maskedb = (PS || 0x01 || salt) xor dbmask. We compute maskeddb directly
919 *f0865ec9SKyle Evans          * in dbmask.
920 *f0865ec9SKyle Evans          */
921 *f0865ec9SKyle Evans 
922 *f0865ec9SKyle Evans         /* 1) PS is made of 0 so xoring it with first pslen bytes of dbmask is a NOP */
923 *f0865ec9SKyle Evans 
924 *f0865ec9SKyle Evans         /*
925 *f0865ec9SKyle Evans          * 2) the byte after padding string is 0x01. Do the xor with the associated
926 *f0865ec9SKyle Evans          *    byte in dbmask
927 *f0865ec9SKyle Evans          */
928 *f0865ec9SKyle Evans         dbmask[pslen] ^= 0x01;
929 *f0865ec9SKyle Evans 
930 *f0865ec9SKyle Evans         /* 3) xor the salt with the end of dbmask */
931 *f0865ec9SKyle Evans         for (i = 0; i < saltlen; i++){
932 *f0865ec9SKyle Evans                 dbmask[dblen - saltlen + i] ^= salt[i];
933 *f0865ec9SKyle Evans         }
934 *f0865ec9SKyle Evans 
935 *f0865ec9SKyle Evans 	/* Set the leftmost 8emLen - emBits bits of the leftmost octet
936 *f0865ec9SKyle Evans 	 * in maskedDB to zero.
937 *f0865ec9SKyle Evans 	 */
938 *f0865ec9SKyle Evans 	mask = 0;
939 *f0865ec9SKyle Evans 	for(i = 0; i < (8 - ((8*emlen) - embits)); i++){
940 *f0865ec9SKyle Evans 		mask = (u8)(mask | (0x1 << i));
941 *f0865ec9SKyle Evans 	}
942 *f0865ec9SKyle Evans 	dbmask[0] &= mask;
943 *f0865ec9SKyle Evans 	/* EM = maskedDB || H || 0xbc */
944 *f0865ec9SKyle Evans 	ret = local_memcpy(&em[dblen], h, hlen); EG(ret, err);
945 *f0865ec9SKyle Evans 	em[emlen - 1] = 0xbc;
946 *f0865ec9SKyle Evans 	(*eminlen) = (u16)emlen;
947 *f0865ec9SKyle Evans 
948 *f0865ec9SKyle Evans err:
949 *f0865ec9SKyle Evans 	return ret;
950 *f0865ec9SKyle Evans }
951 *f0865ec9SKyle Evans 
952 *f0865ec9SKyle Evans /* EMSA-PSS-VERIFY verification as described in RFC 8017 section 9.1.2
953 *f0865ec9SKyle Evans  * NOTE: we enforce MGF1 as a mask generation function
954 *f0865ec9SKyle Evans  */
emsa_pss_verify(const u8 * m,u32 mlen,const u8 * em,u32 embits,u16 emlen,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type,u32 saltlen)955 *f0865ec9SKyle Evans int emsa_pss_verify(const u8 *m, u32 mlen, const u8 *em,
956 *f0865ec9SKyle Evans                     u32 embits, u16 emlen,
957 *f0865ec9SKyle Evans 		    gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type,
958 *f0865ec9SKyle Evans                     u32 saltlen)
959 *f0865ec9SKyle Evans {
960 *f0865ec9SKyle Evans 	int ret, cmp;
961 *f0865ec9SKyle Evans 	u8 hlen, block_size;
962 *f0865ec9SKyle Evans 	u8 mhash[MAX_DIGEST_SIZE];
963 *f0865ec9SKyle Evans 	u8 h_[MAX_DIGEST_SIZE];
964 *f0865ec9SKyle Evans 	u8 zeroes[8];
965 *f0865ec9SKyle Evans 	const u8 *input[2] = { m, NULL };
966 *f0865ec9SKyle Evans 	u32 ilens[2] = { mlen, 0 };
967 *f0865ec9SKyle Evans 	unsigned int i;
968 *f0865ec9SKyle Evans 	u8 mask;
969 *f0865ec9SKyle Evans 	u16 _emlen;
970 *f0865ec9SKyle Evans 	/*
971 *f0865ec9SKyle Evans 	 * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here.
972 *f0865ec9SKyle Evans 	 */
973 *f0865ec9SKyle Evans 	u8 dbmask[NN_USABLE_MAX_BYTE_LEN];
974 *f0865ec9SKyle Evans 	u8 *db;
975 *f0865ec9SKyle Evans 	const u8 *h, *salt, *maskeddb = em;
976 *f0865ec9SKyle Evans 	u32 dblen;
977 *f0865ec9SKyle Evans 	const u8 *input_[4];
978 *f0865ec9SKyle Evans 	u32 ilens_[4];
979 *f0865ec9SKyle Evans 
980 *f0865ec9SKyle Evans 	/* Zeroize local variables */
981 *f0865ec9SKyle Evans 	ret = local_memset(mhash, 0, sizeof(mhash)); EG(ret, err);
982 *f0865ec9SKyle Evans 	ret = local_memset(h_, 0, sizeof(h_)); EG(ret, err);
983 *f0865ec9SKyle Evans 	ret = local_memset(dbmask, 0, sizeof(dbmask)); EG(ret, err);
984 *f0865ec9SKyle Evans 	ret = local_memset(zeroes, 0, sizeof(zeroes)); EG(ret, err);
985 *f0865ec9SKyle Evans 	ret = local_memset(input_, 0, sizeof(input_)); EG(ret, err);
986 *f0865ec9SKyle Evans 	ret = local_memset(ilens_, 0, sizeof(ilens_)); EG(ret, err);
987 *f0865ec9SKyle Evans 
988 *f0865ec9SKyle Evans 	/* Sanity checks */
989 *f0865ec9SKyle Evans 	MUST_HAVE((m != NULL) && (em != NULL), ret, err);
990 *f0865ec9SKyle Evans 
991 *f0865ec9SKyle Evans 	/* Get the used hash information */
992 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err);
993 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
994 *f0865ec9SKyle Evans 
995 *f0865ec9SKyle Evans 	/* Let mHash = Hash(M), an octet string of length hLen */
996 *f0865ec9SKyle Evans 	ret = gen_hash_hfunc_scattered(input, ilens, mhash, gen_hash_type); EG(ret, err);
997 *f0865ec9SKyle Evans 
998 *f0865ec9SKyle Evans 	/* emBits at least 8hLen + 8sLen + 9 */
999 *f0865ec9SKyle Evans 	MUST_HAVE((embits >= ((8*(u32)hlen) + (8*(u32)saltlen) + 9)), ret, err);
1000 *f0865ec9SKyle Evans 
1001 *f0865ec9SKyle Evans 	/* Check that emLen == \ceil(emBits/8) */
1002 *f0865ec9SKyle Evans 	MUST_HAVE((((embits / 8) + 1) < (u32)((u32)0x1 << 16)), ret, err);
1003 *f0865ec9SKyle Evans 	_emlen = ((embits % 8) == 0) ? (u16)(embits / 8) : (u16)((embits / 8) + 1);
1004 *f0865ec9SKyle Evans 	MUST_HAVE((_emlen == emlen), ret, err);
1005 *f0865ec9SKyle Evans 
1006 *f0865ec9SKyle Evans 	/* If emLen < hLen + sLen + 2, output "inconsistent" and stop */
1007 *f0865ec9SKyle Evans 	MUST_HAVE((emlen >= ((u32)hlen + (u32)saltlen + 2)), ret, err);
1008 *f0865ec9SKyle Evans 
1009 *f0865ec9SKyle Evans 	/* If the rightmost octet of EM does not have hexadecimal value 0xbc, output "inconsistent" and stop */
1010 *f0865ec9SKyle Evans 	MUST_HAVE((em[emlen - 1] == 0xbc), ret, err);
1011 *f0865ec9SKyle Evans 
1012 *f0865ec9SKyle Evans 	/* If the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB are not all equal to zero,
1013 *f0865ec9SKyle Evans 	 * output "inconsistent" and stop
1014 *f0865ec9SKyle Evans 	 * NOTE: maskeddb points to &em[0]
1015 *f0865ec9SKyle Evans 	 */
1016 *f0865ec9SKyle Evans 	mask = 0;
1017 *f0865ec9SKyle Evans 	for(i = 0; i < (8 - ((unsigned int)(8*emlen) - embits)); i++){
1018 *f0865ec9SKyle Evans 		mask = (u8)(mask | (0x1 << i));
1019 *f0865ec9SKyle Evans 	}
1020 *f0865ec9SKyle Evans 	MUST_HAVE(((maskeddb[0] & (~mask)) == 0), ret, err);
1021 *f0865ec9SKyle Evans 
1022 *f0865ec9SKyle Evans 	/* dbMask = MGF(H, emLen - hLen - 1) */
1023 *f0865ec9SKyle Evans 	dblen = (u32)(emlen - hlen - 1);
1024 *f0865ec9SKyle Evans 	h = &em[dblen];
1025 *f0865ec9SKyle Evans 	MUST_HAVE(((u16)dblen <= sizeof(dbmask)), ret, err); /* sanity check for overflow */
1026 *f0865ec9SKyle Evans 	ret = _mgf1(h, hlen, dbmask, dblen, mgf_hash_type); EG(ret, err);
1027 *f0865ec9SKyle Evans 	/* DB = maskedDB \xor dbMask */
1028 *f0865ec9SKyle Evans 	db = &dbmask[0];
1029 *f0865ec9SKyle Evans 	for(i = 0; i < (u16)dblen; i++){
1030 *f0865ec9SKyle Evans 		db[i] = (dbmask[i] ^ maskeddb[i]);
1031 *f0865ec9SKyle Evans 	}
1032 *f0865ec9SKyle Evans 	/* Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero */
1033 *f0865ec9SKyle Evans 	db[0] &= mask;
1034 *f0865ec9SKyle Evans 
1035 *f0865ec9SKyle Evans 	/*
1036 *f0865ec9SKyle Evans 	 * If the emLen - hLen - sLen - 2 leftmost octets of DB are not
1037 *f0865ec9SKyle Evans          * zero or if the octet at position emLen - hLen - sLen - 1 (the
1038 *f0865ec9SKyle Evans          * leftmost position is "position 1") does not have hexadecimal
1039 *f0865ec9SKyle Evans          * value 0x01, output "inconsistent" and stop.
1040 *f0865ec9SKyle Evans 	 */
1041 *f0865ec9SKyle Evans 	for(i = 0; i < (u16)(dblen - saltlen - 1); i++){
1042 *f0865ec9SKyle Evans 		MUST_HAVE((db[i] == 0x00), ret, err);
1043 *f0865ec9SKyle Evans 	}
1044 *f0865ec9SKyle Evans 	MUST_HAVE((db[dblen - saltlen - 1] == 0x01), ret, err);
1045 *f0865ec9SKyle Evans 
1046 *f0865ec9SKyle Evans 	/* Let salt be the last sLen octets of DB */
1047 *f0865ec9SKyle Evans 	salt = &db[dblen - saltlen];
1048 *f0865ec9SKyle Evans 	/*
1049 *f0865ec9SKyle Evans 	 * Let H' = Hash(M'), an octet string of length hLen with
1050 *f0865ec9SKyle Evans 	 *     M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt
1051 *f0865ec9SKyle Evans 	 */
1052 *f0865ec9SKyle Evans 	/* Fill input_ */
1053 *f0865ec9SKyle Evans 	input_[0] = zeroes;
1054 *f0865ec9SKyle Evans 	input_[1] = mhash;
1055 *f0865ec9SKyle Evans 	input_[2] = salt;
1056 *f0865ec9SKyle Evans 	input_[3] = NULL;
1057 *f0865ec9SKyle Evans 	/* Fill ilens_ */
1058 *f0865ec9SKyle Evans 	ilens_[0] = sizeof(zeroes);
1059 *f0865ec9SKyle Evans 	ilens_[1] = hlen;
1060 *f0865ec9SKyle Evans 	ilens_[2] = saltlen;
1061 *f0865ec9SKyle Evans 	ilens_[3] = 0;
1062 *f0865ec9SKyle Evans 	/* Hash */
1063 *f0865ec9SKyle Evans 	ret = gen_hash_hfunc_scattered(input_, ilens_, h_, gen_hash_type); EG(ret, err);
1064 *f0865ec9SKyle Evans 
1065 *f0865ec9SKyle Evans 	/* If H = H', output "consistent".  Otherwise, output "inconsistent" */
1066 *f0865ec9SKyle Evans 	ret = are_equal(h, h_, hlen, &cmp); EG(ret, err);
1067 *f0865ec9SKyle Evans 	if(!cmp){
1068 *f0865ec9SKyle Evans 		ret = -1;
1069 *f0865ec9SKyle Evans 	}
1070 *f0865ec9SKyle Evans 
1071 *f0865ec9SKyle Evans err:
1072 *f0865ec9SKyle Evans 	return ret;
1073 *f0865ec9SKyle Evans }
1074 *f0865ec9SKyle Evans 
1075 *f0865ec9SKyle Evans /* EMSA-PKCS1-v1_5 encoding as described in RFC 8017 section 9.2
1076 *f0865ec9SKyle Evans  */
emsa_pkcs1_v1_5_encode(const u8 * m,u32 mlen,u8 * em,u16 emlen,gen_hash_alg_type gen_hash_type)1077 *f0865ec9SKyle Evans int emsa_pkcs1_v1_5_encode(const u8 *m, u32 mlen, u8 *em, u16 emlen,
1078 *f0865ec9SKyle Evans                            gen_hash_alg_type gen_hash_type)
1079 *f0865ec9SKyle Evans {
1080 *f0865ec9SKyle Evans 	int ret;
1081 *f0865ec9SKyle Evans 	const u8 *input[2] = { m, NULL };
1082 *f0865ec9SKyle Evans 	u32 ilens[2] = { mlen, 0 };
1083 *f0865ec9SKyle Evans 	u8 digest_size, block_size;
1084 *f0865ec9SKyle Evans 	u8 digest[MAX_DIGEST_SIZE];
1085 *f0865ec9SKyle Evans 	u32 digestinfo_len = 0;
1086 *f0865ec9SKyle Evans 	u32 tlen = 0;
1087 *f0865ec9SKyle Evans 
1088 *f0865ec9SKyle Evans 	/* Zeroize local variables */
1089 *f0865ec9SKyle Evans 	ret = local_memset(digest, 0, sizeof(digest)); EG(ret, err);
1090 *f0865ec9SKyle Evans 
1091 *f0865ec9SKyle Evans 	/* Compute H = Hash(M) */
1092 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(gen_hash_type, &digest_size, &block_size); EG(ret, err);
1093 *f0865ec9SKyle Evans 	MUST_HAVE((digest_size <= MAX_DIGEST_SIZE), ret, err);
1094 *f0865ec9SKyle Evans 	ret = gen_hash_hfunc_scattered(input, ilens, digest, gen_hash_type); EG(ret, err);
1095 *f0865ec9SKyle Evans 
1096 *f0865ec9SKyle Evans 	/* Now encode:
1097 *f0865ec9SKyle Evans 	 *
1098 *f0865ec9SKyle Evans          *     DigestInfo ::= SEQUENCE {
1099 *f0865ec9SKyle Evans          *         digestAlgorithm AlgorithmIdentifier,
1100 *f0865ec9SKyle Evans          *         digest OCTET STRING
1101 *f0865ec9SKyle Evans          *     }
1102 *f0865ec9SKyle Evans 	 */
1103 *f0865ec9SKyle Evans 	digestinfo_len = emlen;
1104 *f0865ec9SKyle Evans 	/* NOTE: the rsa_digestinfo_from_hash returns the size of DigestInfo *WITHOUT* the
1105 *f0865ec9SKyle Evans 	 * appended raw hash, tlen is the real size of the complete encoded DigestInfo.
1106 *f0865ec9SKyle Evans 	 */
1107 *f0865ec9SKyle Evans 	ret = rsa_digestinfo_from_hash(gen_hash_type, em, &digestinfo_len); EG(ret, err);
1108 *f0865ec9SKyle Evans 	tlen = (digestinfo_len + digest_size);
1109 *f0865ec9SKyle Evans 
1110 *f0865ec9SKyle Evans 	/* If emLen < tLen + 11, output "intended encoded message length too short" and stop */
1111 *f0865ec9SKyle Evans 	MUST_HAVE((emlen >= (tlen + 11)), ret, err);
1112 *f0865ec9SKyle Evans 
1113 *f0865ec9SKyle Evans 	/* Copy T at the end of em */
1114 *f0865ec9SKyle Evans 	digestinfo_len = emlen;
1115 *f0865ec9SKyle Evans 	ret = rsa_digestinfo_from_hash(gen_hash_type, &em[emlen - tlen], &digestinfo_len); EG(ret, err);
1116 *f0865ec9SKyle Evans 	ret = local_memcpy(&em[emlen - tlen + digestinfo_len], digest, digest_size); EG(ret, err);
1117 *f0865ec9SKyle Evans 
1118 *f0865ec9SKyle Evans 	/*
1119 *f0865ec9SKyle Evans 	 * Format 0x00 || 0x01 || PS || 0x00 before
1120 *f0865ec9SKyle Evans 	 */
1121 *f0865ec9SKyle Evans 	em[0] = 0x00;
1122 *f0865ec9SKyle Evans 	em[1] = 0x01;
1123 *f0865ec9SKyle Evans 	em[emlen - tlen - 1] = 0x00;
1124 *f0865ec9SKyle Evans 	ret = local_memset(&em[2], 0xff, emlen - tlen - 3);
1125 *f0865ec9SKyle Evans 
1126 *f0865ec9SKyle Evans err:
1127 *f0865ec9SKyle Evans 	return ret;
1128 *f0865ec9SKyle Evans }
1129 *f0865ec9SKyle Evans 
1130 *f0865ec9SKyle Evans /****************************************************************/
1131 *f0865ec9SKyle Evans /******** Encryption schemes *************************************/
1132 *f0865ec9SKyle Evans /* The RSAES-PKCS1-V1_5-ENCRYPT algorithm as described in RFC 8017 section 7.2.1
1133 *f0865ec9SKyle Evans  *
1134 *f0865ec9SKyle Evans  */
rsaes_pkcs1_v1_5_encrypt(const rsa_pub_key * pub,const u8 * m,u32 mlen,u8 * c,u32 * clen,u32 modbits,const u8 * forced_seed,u32 seedlen)1135 *f0865ec9SKyle Evans int rsaes_pkcs1_v1_5_encrypt(const rsa_pub_key *pub, const u8 *m, u32 mlen,
1136 *f0865ec9SKyle Evans                              u8 *c, u32 *clen, u32 modbits,
1137 *f0865ec9SKyle Evans                              const u8 *forced_seed, u32 seedlen)
1138 *f0865ec9SKyle Evans {
1139 *f0865ec9SKyle Evans 	int ret;
1140 *f0865ec9SKyle Evans 	u32 k;
1141 *f0865ec9SKyle Evans 	u8 *em = c;
1142 *f0865ec9SKyle Evans 	unsigned int i;
1143 *f0865ec9SKyle Evans 	nn m_, c_;
1144 *f0865ec9SKyle Evans 	m_.magic = c_.magic = WORD(0);
1145 *f0865ec9SKyle Evans 
1146 *f0865ec9SKyle Evans 	MUST_HAVE((clen != NULL) && (c != NULL) && (m != NULL), ret, err);
1147 *f0865ec9SKyle Evans 
1148 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1149 *f0865ec9SKyle Evans 
1150 *f0865ec9SKyle Evans 	/* Check on lengths */
1151 *f0865ec9SKyle Evans 	MUST_HAVE((k >= 11), ret, err);
1152 *f0865ec9SKyle Evans 	MUST_HAVE((mlen <= (k - 11)), ret, err);
1153 *f0865ec9SKyle Evans 	MUST_HAVE(((*clen) >= k), ret, err);
1154 *f0865ec9SKyle Evans 
1155 *f0865ec9SKyle Evans 	/* EME-PKCS1-v1_5 encoding EM = 0x00 || 0x02 || PS || 0x00 || M */
1156 *f0865ec9SKyle Evans 	em[0] = 0x00;
1157 *f0865ec9SKyle Evans 	em[1] = 0x02;
1158 *f0865ec9SKyle Evans 	if(forced_seed == NULL){
1159 *f0865ec9SKyle Evans 		for(i = 0; i < (k - mlen - 3); i++){
1160 *f0865ec9SKyle Evans 			u8 rand_byte = 0;
1161 *f0865ec9SKyle Evans 			while (!rand_byte) {
1162 *f0865ec9SKyle Evans 				ret = get_random(&rand_byte, 1); EG(ret, err);
1163 *f0865ec9SKyle Evans 			}
1164 *f0865ec9SKyle Evans 			em[2 + i] = rand_byte;
1165 *f0865ec9SKyle Evans 		}
1166 *f0865ec9SKyle Evans 	}
1167 *f0865ec9SKyle Evans 	else{
1168 *f0865ec9SKyle Evans 		MUST_HAVE((seedlen == (k - mlen - 3)), ret, err);
1169 *f0865ec9SKyle Evans 		/* Check that the forced seed does not contain 0x00 */
1170 *f0865ec9SKyle Evans 		for(i = 0; i < seedlen; i++){
1171 *f0865ec9SKyle Evans 			MUST_HAVE((forced_seed[i] != 0), ret, err);
1172 *f0865ec9SKyle Evans 		}
1173 *f0865ec9SKyle Evans 		ret = local_memcpy(&em[2], forced_seed, seedlen); EG(ret, err);
1174 *f0865ec9SKyle Evans 	}
1175 *f0865ec9SKyle Evans 	em[k - mlen - 1] = 0x00;
1176 *f0865ec9SKyle Evans 	ret = local_memcpy(&em[k - mlen], m, mlen); EG(ret, err);
1177 *f0865ec9SKyle Evans 
1178 *f0865ec9SKyle Evans 	/* RSA encryption */
1179 *f0865ec9SKyle Evans 	/*   m = OS2IP (EM) */
1180 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1181 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&m_, em, (u16)k); EG(ret, err);
1182 *f0865ec9SKyle Evans 	/*   c = RSAEP ((n, e), m) */
1183 *f0865ec9SKyle Evans 	ret = rsaep(pub, &m_, &c_); EG(ret, err);
1184 *f0865ec9SKyle Evans 	/*   C = I2OSP (c, k) */
1185 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&c_, c, (u16)k); EG(ret, err);
1186 *f0865ec9SKyle Evans 	(*clen) = (u16)k;
1187 *f0865ec9SKyle Evans 
1188 *f0865ec9SKyle Evans err:
1189 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1190 *f0865ec9SKyle Evans 	nn_uninit(&c_);
1191 *f0865ec9SKyle Evans 	/* Zeroify in case of error */
1192 *f0865ec9SKyle Evans 	if(ret && (clen != NULL)){
1193 *f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(c, 0, (*clen)));
1194 *f0865ec9SKyle Evans 	}
1195 *f0865ec9SKyle Evans 
1196 *f0865ec9SKyle Evans 	return ret;
1197 *f0865ec9SKyle Evans }
1198 *f0865ec9SKyle Evans 
1199 *f0865ec9SKyle Evans /* The RSAES-PKCS1-V1_5-DECRYPT algorithm as described in RFC 8017 section 7.2.2
1200 *f0865ec9SKyle Evans  *
1201 *f0865ec9SKyle Evans  */
_rsaes_pkcs1_v1_5_decrypt(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * c,u32 clen,u8 * m,u32 * mlen,u32 modbits)1202 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsaes_pkcs1_v1_5_decrypt(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen,
1203 *f0865ec9SKyle Evans                              u8 *m, u32 *mlen, u32 modbits)
1204 *f0865ec9SKyle Evans {
1205 *f0865ec9SKyle Evans 	int ret;
1206 *f0865ec9SKyle Evans 	unsigned int i, pos;
1207 *f0865ec9SKyle Evans 	u32 k;
1208 *f0865ec9SKyle Evans 	u8 r;
1209 *f0865ec9SKyle Evans 	u8 *em = m;
1210 *f0865ec9SKyle Evans 	nn m_, c_;
1211 *f0865ec9SKyle Evans 	m_.magic = c_.magic = WORD(0);
1212 *f0865ec9SKyle Evans 
1213 *f0865ec9SKyle Evans 	MUST_HAVE((mlen != NULL) && (c != NULL) && (m != NULL), ret, err);
1214 *f0865ec9SKyle Evans 
1215 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1216 *f0865ec9SKyle Evans 
1217 *f0865ec9SKyle Evans 	/* Check on lengths */
1218 *f0865ec9SKyle Evans 	MUST_HAVE((clen == k) && (k >= 11), ret, err);
1219 *f0865ec9SKyle Evans 	MUST_HAVE(((*mlen) >= k), ret, err);
1220 *f0865ec9SKyle Evans 
1221 *f0865ec9SKyle Evans 	/* RSA decryption */
1222 *f0865ec9SKyle Evans 	/*   c = OS2IP (C) */
1223 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&c_, c, clen); EG(ret, err);
1224 *f0865ec9SKyle Evans 	/*   m = RSADP ((n, d), c) */
1225 *f0865ec9SKyle Evans 	if(pub != NULL){
1226 *f0865ec9SKyle Evans 		ret = rsadp_hardened(priv, pub, &c_, &m_); EG(ret, err);
1227 *f0865ec9SKyle Evans 	}
1228 *f0865ec9SKyle Evans 	else{
1229 *f0865ec9SKyle Evans 		ret = rsadp(priv, &c_, &m_); EG(ret, err);
1230 *f0865ec9SKyle Evans 	}
1231 *f0865ec9SKyle Evans 	/*   EM = I2OSP (m, k) */
1232 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1233 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&m_, em, (u16)k); EG(ret, err);
1234 *f0865ec9SKyle Evans 
1235 *f0865ec9SKyle Evans 	/* EME-PKCS1-v1_5 decoding: EM = 0x00 || 0x02 || PS || 0x00 || M */
1236 *f0865ec9SKyle Evans 	/* NOTE: we try our best to do the following in constant time to
1237 *f0865ec9SKyle Evans 	 * limit padding oracles here (see Bleichenbacher attacks).
1238 *f0865ec9SKyle Evans 	 */
1239 *f0865ec9SKyle Evans 	ret = (1 - (!!(em[0] == 0x00) & !!(em[1] == 0x02)));
1240 *f0865ec9SKyle Evans 	pos = 0;
1241 *f0865ec9SKyle Evans 	/* Handle the first zero octet after PS in constant time */
1242 *f0865ec9SKyle Evans 	for(i = 2; i < k; i++){
1243 *f0865ec9SKyle Evans 		unsigned int mask = !!(em[i] == 0x00) & !!(pos == 0);
1244 *f0865ec9SKyle Evans 		pos = (mask * i) + ((1 - mask) * pos);
1245 *f0865ec9SKyle Evans 	}
1246 *f0865ec9SKyle Evans 	ret |= !(pos >= (2 + 8)); /* PS length is at least 8 (also implying we found a 0x00) */
1247 *f0865ec9SKyle Evans 	pos = (pos == 0) ? pos : (pos + 1);
1248 *f0865ec9SKyle Evans 	/* We get a random value between 2 and k if we have an error so that
1249 *f0865ec9SKyle Evans 	 * we put a random value in pos.
1250 *f0865ec9SKyle Evans 	 */
1251 *f0865ec9SKyle Evans         ret |= get_random((u8*)&i, 4);
1252 *f0865ec9SKyle Evans 	/* Get a random value r for later loop dummy operations */
1253 *f0865ec9SKyle Evans 	ret |= get_random(&r, 1);
1254 *f0865ec9SKyle Evans 	/* Update pos with random value in case of error to progress
1255 *f0865ec9SKyle Evans 	 * nominally with the algorithm
1256 *f0865ec9SKyle Evans 	 */
1257 *f0865ec9SKyle Evans 	pos = (ret) ? ((i % (k - 2)) + 2) : pos;
1258 *f0865ec9SKyle Evans 	for(i = 2; i < k; i++){
1259 *f0865ec9SKyle Evans 		u8 r_;
1260 *f0865ec9SKyle Evans 		unsigned int idx;
1261 *f0865ec9SKyle Evans 		/* Replace m by a random value in case of error */
1262 *f0865ec9SKyle Evans 		idx = ((i < pos) ? 0x00 : (i - pos));
1263 *f0865ec9SKyle Evans 		r ^= (u8)i;
1264 *f0865ec9SKyle Evans 		r_ = (u8)((u8)(!!ret) * r);
1265 *f0865ec9SKyle Evans 		m[idx] = (em[i] ^ r_);
1266 *f0865ec9SKyle Evans 	}
1267 *f0865ec9SKyle Evans 	(*mlen) = (u16)(k - pos);
1268 *f0865ec9SKyle Evans 	/* Hide return value details to avoid information leak */
1269 *f0865ec9SKyle Evans 	ret = -(!!ret);
1270 *f0865ec9SKyle Evans 
1271 *f0865ec9SKyle Evans err:
1272 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1273 *f0865ec9SKyle Evans 	nn_uninit(&c_);
1274 *f0865ec9SKyle Evans 
1275 *f0865ec9SKyle Evans 	return ret;
1276 *f0865ec9SKyle Evans }
1277 *f0865ec9SKyle Evans 
1278 *f0865ec9SKyle Evans /*
1279 *f0865ec9SKyle Evans  * Basic version without much SCA/faults protections.
1280 *f0865ec9SKyle Evans  */
rsaes_pkcs1_v1_5_decrypt(const rsa_priv_key * priv,const u8 * c,u32 clen,u8 * m,u32 * mlen,u32 modbits)1281 *f0865ec9SKyle Evans int rsaes_pkcs1_v1_5_decrypt(const rsa_priv_key *priv, const u8 *c, u32 clen,
1282 *f0865ec9SKyle Evans                              u8 *m, u32 *mlen, u32 modbits)
1283 *f0865ec9SKyle Evans {
1284 *f0865ec9SKyle Evans 	return _rsaes_pkcs1_v1_5_decrypt(priv, NULL, c, clen, m, mlen, modbits);
1285 *f0865ec9SKyle Evans }
1286 *f0865ec9SKyle Evans 
1287 *f0865ec9SKyle Evans /*
1288 *f0865ec9SKyle Evans  * Hardened version with some SCA/faults protections.
1289 *f0865ec9SKyle Evans  */
rsaes_pkcs1_v1_5_decrypt_hardened(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * c,u32 clen,u8 * m,u32 * mlen,u32 modbits)1290 *f0865ec9SKyle Evans int rsaes_pkcs1_v1_5_decrypt_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen,
1291 *f0865ec9SKyle Evans                              u8 *m, u32 *mlen, u32 modbits)
1292 *f0865ec9SKyle Evans {
1293 *f0865ec9SKyle Evans 	return _rsaes_pkcs1_v1_5_decrypt(priv, pub, c, clen, m, mlen, modbits);
1294 *f0865ec9SKyle Evans }
1295 *f0865ec9SKyle Evans 
1296 *f0865ec9SKyle Evans /* The RSAES-OAEP-ENCRYPT algorithm as described in RFC 8017 section 7.1.1
1297 *f0865ec9SKyle Evans  *
1298 *f0865ec9SKyle Evans  */
rsaes_oaep_encrypt(const rsa_pub_key * pub,const u8 * m,u32 mlen,u8 * c,u32 * clen,u32 modbits,const u8 * label,u32 label_len,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type,const u8 * forced_seed,u32 seedlen)1299 *f0865ec9SKyle Evans int rsaes_oaep_encrypt(const rsa_pub_key *pub, const u8 *m, u32 mlen,
1300 *f0865ec9SKyle Evans                        u8 *c, u32 *clen, u32 modbits, const u8 *label, u32 label_len,
1301 *f0865ec9SKyle Evans                        gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type,
1302 *f0865ec9SKyle Evans 		       const u8 *forced_seed, u32 seedlen)
1303 *f0865ec9SKyle Evans {
1304 *f0865ec9SKyle Evans 	int ret;
1305 *f0865ec9SKyle Evans 	u32 k, pslen, khlen;
1306 *f0865ec9SKyle Evans 	unsigned int i;
1307 *f0865ec9SKyle Evans 	u8 hlen, block_size;
1308 *f0865ec9SKyle Evans 	u8 *em = c;
1309 *f0865ec9SKyle Evans 	/* Reasonable sizes */
1310 *f0865ec9SKyle Evans 	u8 seed[MAX_DIGEST_SIZE];
1311 *f0865ec9SKyle Evans         /*
1312 *f0865ec9SKyle Evans          * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here.
1313 *f0865ec9SKyle Evans          */
1314 *f0865ec9SKyle Evans 	u8 dbmask[NN_USABLE_MAX_BYTE_LEN];
1315 *f0865ec9SKyle Evans 	u8 db[NN_USABLE_MAX_BYTE_LEN];
1316 *f0865ec9SKyle Evans 	u8 *seedmask = dbmask, *maskedseed = NULL, *maskeddb = NULL;
1317 *f0865ec9SKyle Evans 	const u8 *input[2] = { c, NULL };
1318 *f0865ec9SKyle Evans 	u32 ilens[2] = { 0, 0 };
1319 *f0865ec9SKyle Evans 	nn m_, c_;
1320 *f0865ec9SKyle Evans 	m_.magic = c_.magic = WORD(0);
1321 *f0865ec9SKyle Evans 
1322 *f0865ec9SKyle Evans 	/* Zeroize local variables */
1323 *f0865ec9SKyle Evans 	ret = local_memset(seed, 0, sizeof(seed)); EG(ret, err);
1324 *f0865ec9SKyle Evans 	ret = local_memset(db, 0, sizeof(db)); EG(ret, err);
1325 *f0865ec9SKyle Evans 	ret = local_memset(dbmask, 0, sizeof(dbmask)); EG(ret, err);
1326 *f0865ec9SKyle Evans 
1327 *f0865ec9SKyle Evans 	MUST_HAVE((clen != NULL) && (c != NULL) && (m != NULL), ret, err);
1328 *f0865ec9SKyle Evans 
1329 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1330 *f0865ec9SKyle Evans 
1331 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err);
1332 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
1333 *f0865ec9SKyle Evans 
1334 *f0865ec9SKyle Evans 	/* Check on lengths */
1335 *f0865ec9SKyle Evans 	MUST_HAVE(((u32)k >= ((2 * (u32)hlen) + 2)), ret, err);
1336 *f0865ec9SKyle Evans 	MUST_HAVE(((mlen ) <= ((u32)k - (2 * (u32)hlen) - 2)), ret, err);
1337 *f0865ec9SKyle Evans 	MUST_HAVE(((*clen) >= k), ret, err);
1338 *f0865ec9SKyle Evans 
1339 *f0865ec9SKyle Evans 	/* EME-OAEP encoding: DB = lHash || PS || 0x01 || M */
1340 *f0865ec9SKyle Evans 	/* and then EM = 0x00 || maskedSeed || maskedDB */
1341 *f0865ec9SKyle Evans 	maskedseed = &em[1];
1342 *f0865ec9SKyle Evans 	maskeddb   = &em[hlen + 1];
1343 *f0865ec9SKyle Evans 	MUST_HAVE(((k - hlen - 1) <= sizeof(db)), ret, err);
1344 *f0865ec9SKyle Evans 	if(label == NULL){
1345 *f0865ec9SKyle Evans 		MUST_HAVE((label_len == 0), ret, err);
1346 *f0865ec9SKyle Evans 	}
1347 *f0865ec9SKyle Evans 	else{
1348 *f0865ec9SKyle Evans 		input[0] = label;
1349 *f0865ec9SKyle Evans 		ilens[0] = label_len;
1350 *f0865ec9SKyle Evans 	}
1351 *f0865ec9SKyle Evans 	ret = gen_hash_hfunc_scattered(input, ilens, &db[0], gen_hash_type); EG(ret, err);
1352 *f0865ec9SKyle Evans 	/*
1353 *f0865ec9SKyle Evans 	 * 2.b. Generate a padding string PS consisting of k - mLen - 2hLen -
1354 *f0865ec9SKyle Evans 	 * 2 zero octets. The length of PS may be zero.
1355 *f0865ec9SKyle Evans 	 *
1356 *f0865ec9SKyle Evans 	 * DB = lHash || PS || 0x01 || M. Hence, PS starts at octet hlen in DB
1357 *f0865ec9SKyle Evans 	 */
1358 *f0865ec9SKyle Evans 	pslen = (k - mlen - (u32)(2 * hlen) - 2);
1359 *f0865ec9SKyle Evans 	for(i = 0; i < pslen; i++){
1360 *f0865ec9SKyle Evans 		db[hlen + i] = 0x00;
1361 *f0865ec9SKyle Evans 	}
1362 *f0865ec9SKyle Evans 	/* 0x01 || M */
1363 *f0865ec9SKyle Evans 	db[hlen + pslen] = 0x01;
1364 *f0865ec9SKyle Evans 	for(i = 0 ; i < mlen; i++){
1365 *f0865ec9SKyle Evans 		db[hlen + pslen + 1 + i] = m[i];
1366 *f0865ec9SKyle Evans 	}
1367 *f0865ec9SKyle Evans 	/* Generate a random octet string seed of length hLen */
1368 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= sizeof(seed)), ret, err);
1369 *f0865ec9SKyle Evans 	if(forced_seed != NULL){
1370 *f0865ec9SKyle Evans 		MUST_HAVE((seedlen == hlen), ret, err);
1371 *f0865ec9SKyle Evans 		ret = local_memcpy(seed, forced_seed, seedlen); EG(ret, err);
1372 *f0865ec9SKyle Evans 	}
1373 *f0865ec9SKyle Evans 	else{
1374 *f0865ec9SKyle Evans 		ret = get_random(seed, hlen); EG(ret, err);
1375 *f0865ec9SKyle Evans 	}
1376 *f0865ec9SKyle Evans 	/* Let dbMask = MGF(seed, k - hLen - 1)*/
1377 *f0865ec9SKyle Evans 	khlen = (k - hlen - 1);
1378 *f0865ec9SKyle Evans 	MUST_HAVE((khlen <= sizeof(dbmask)), ret, err);
1379 *f0865ec9SKyle Evans 	ret = _mgf1(seed, hlen, dbmask, khlen, mgf_hash_type); EG(ret, err);
1380 *f0865ec9SKyle Evans 	/* Let maskedDB = DB \xor dbMask */
1381 *f0865ec9SKyle Evans 	for(i = 0; i < khlen; i++){
1382 *f0865ec9SKyle Evans 		maskeddb[i] = (db[i] ^ dbmask[i]);
1383 *f0865ec9SKyle Evans 	}
1384 *f0865ec9SKyle Evans 	/* Let seedMask = MGF(maskedDB, hLen) */
1385 *f0865ec9SKyle Evans 	MUST_HAVE((khlen < (u32)((u32)0x1 << 16)), ret, err);
1386 *f0865ec9SKyle Evans 	ret = _mgf1(maskeddb, (u16)khlen, seedmask, hlen, mgf_hash_type); EG(ret, err);
1387 *f0865ec9SKyle Evans 	/* Let maskedSeed = seed \xor seedMask */
1388 *f0865ec9SKyle Evans 	for(i = 0; i < hlen; i++){
1389 *f0865ec9SKyle Evans 		maskedseed[i] = (seed[i] ^ seedmask[i]);
1390 *f0865ec9SKyle Evans 	}
1391 *f0865ec9SKyle Evans 	/* EM = 0x00 || maskedSeed || maskedDB should be filled */
1392 *f0865ec9SKyle Evans 	em[0] = 0x00;
1393 *f0865ec9SKyle Evans 
1394 *f0865ec9SKyle Evans 	/* RSA encryption */
1395 *f0865ec9SKyle Evans 	/*   m = OS2IP (EM) */
1396 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1397 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&m_, em, (u16)k); EG(ret, err);
1398 *f0865ec9SKyle Evans 	/*   c = RSAEP ((n, e), m) */
1399 *f0865ec9SKyle Evans 	ret = rsaep(pub, &m_, &c_); EG(ret, err);
1400 *f0865ec9SKyle Evans 	/*   C = I2OSP (c, k) */
1401 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&c_, c, (u16)k); EG(ret, err);
1402 *f0865ec9SKyle Evans 	(*clen) = (u16)k;
1403 *f0865ec9SKyle Evans 
1404 *f0865ec9SKyle Evans err:
1405 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1406 *f0865ec9SKyle Evans 	nn_uninit(&c_);
1407 *f0865ec9SKyle Evans 	/* Zeroify in case of error */
1408 *f0865ec9SKyle Evans 	if(ret && (clen != NULL)){
1409 *f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(c, 0, (*clen)));
1410 *f0865ec9SKyle Evans 	}
1411 *f0865ec9SKyle Evans 
1412 *f0865ec9SKyle Evans 	return ret;
1413 *f0865ec9SKyle Evans }
1414 *f0865ec9SKyle Evans 
1415 *f0865ec9SKyle Evans /* The RSAES-OAEP-DECRYPT algorithm as described in RFC 8017 section 7.1.2
1416 *f0865ec9SKyle Evans  *
1417 *f0865ec9SKyle Evans  */
_rsaes_oaep_decrypt(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * c,u32 clen,u8 * m,u32 * mlen,u32 modbits,const u8 * label,u32 label_len,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type)1418 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsaes_oaep_decrypt(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen,
1419 *f0865ec9SKyle Evans                        u8 *m, u32 *mlen, u32 modbits,
1420 *f0865ec9SKyle Evans                        const u8 *label, u32 label_len, gen_hash_alg_type gen_hash_type,
1421 *f0865ec9SKyle Evans 		       gen_hash_alg_type mgf_hash_type)
1422 *f0865ec9SKyle Evans {
1423 *f0865ec9SKyle Evans 	int ret, cmp;
1424 *f0865ec9SKyle Evans 	u32 k, khlen;
1425 *f0865ec9SKyle Evans 	unsigned int i, pos;
1426 *f0865ec9SKyle Evans 	u8 hlen, block_size;
1427 *f0865ec9SKyle Evans 	u8 *em = m;
1428 *f0865ec9SKyle Evans 	u8 r;
1429 *f0865ec9SKyle Evans 	/* Reasonable sizes */
1430 *f0865ec9SKyle Evans 	u8 lhash[MAX_DIGEST_SIZE];
1431 *f0865ec9SKyle Evans 	u8 seedmask[MAX_DIGEST_SIZE];
1432 *f0865ec9SKyle Evans         /*
1433 *f0865ec9SKyle Evans          * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here.
1434 *f0865ec9SKyle Evans          */
1435 *f0865ec9SKyle Evans 	u8 dbmask[NN_USABLE_MAX_BYTE_LEN];
1436 *f0865ec9SKyle Evans 	u8 *seed = seedmask, *maskedseed = NULL, *maskeddb = NULL, *db = NULL;
1437 *f0865ec9SKyle Evans 	const u8 *input[2] = { c, NULL };
1438 *f0865ec9SKyle Evans 	u32 ilens[2] = { 0, 0 };
1439 *f0865ec9SKyle Evans 	nn m_, c_;
1440 *f0865ec9SKyle Evans 	m_.magic = c_.magic = WORD(0);
1441 *f0865ec9SKyle Evans 
1442 *f0865ec9SKyle Evans 	/* Zeroize local variables */
1443 *f0865ec9SKyle Evans 	ret = local_memset(lhash, 0, sizeof(lhash)); EG(ret, err);
1444 *f0865ec9SKyle Evans 	ret = local_memset(seedmask, 0, sizeof(seedmask)); EG(ret, err);
1445 *f0865ec9SKyle Evans 	ret = local_memset(dbmask, 0, sizeof(dbmask)); EG(ret, err);
1446 *f0865ec9SKyle Evans 
1447 *f0865ec9SKyle Evans 	MUST_HAVE((c != NULL) && (m != NULL), ret, err);
1448 *f0865ec9SKyle Evans 
1449 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1450 *f0865ec9SKyle Evans 
1451 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err);
1452 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
1453 *f0865ec9SKyle Evans 
1454 *f0865ec9SKyle Evans 	/* Check on lengths */
1455 *f0865ec9SKyle Evans 	MUST_HAVE((clen == k), ret, err);
1456 *f0865ec9SKyle Evans 	MUST_HAVE(((u32)k >= ((2 * (u32)hlen) + 2)), ret, err);
1457 *f0865ec9SKyle Evans 
1458 *f0865ec9SKyle Evans 	/* RSA decryption */
1459 *f0865ec9SKyle Evans 	/*   c = OS2IP (C) */
1460 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&c_, c, clen); EG(ret, err);
1461 *f0865ec9SKyle Evans 	/*   m = RSADP ((n, d), c) */
1462 *f0865ec9SKyle Evans 	if(pub != NULL){
1463 *f0865ec9SKyle Evans 		ret = rsadp_hardened(priv, pub, &c_, &m_); EG(ret, err);
1464 *f0865ec9SKyle Evans 	}
1465 *f0865ec9SKyle Evans 	else{
1466 *f0865ec9SKyle Evans 		ret = rsadp(priv, &c_, &m_); EG(ret, err);
1467 *f0865ec9SKyle Evans 	}
1468 *f0865ec9SKyle Evans 	/*   EM = I2OSP (m, k) */
1469 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1470 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&m_, em, (u16)k); EG(ret, err);
1471 *f0865ec9SKyle Evans 
1472 *f0865ec9SKyle Evans 	/* EME-OAEP decoding */
1473 *f0865ec9SKyle Evans 	/* lHash = Hash(L) */
1474 *f0865ec9SKyle Evans 	if(label == NULL){
1475 *f0865ec9SKyle Evans 		MUST_HAVE((label_len == 0), ret, err);
1476 *f0865ec9SKyle Evans 	}
1477 *f0865ec9SKyle Evans 	else{
1478 *f0865ec9SKyle Evans 		input[0] = label;
1479 *f0865ec9SKyle Evans 		ilens[0] = label_len;
1480 *f0865ec9SKyle Evans 	}
1481 *f0865ec9SKyle Evans 	ret = gen_hash_hfunc_scattered(input, ilens, lhash, gen_hash_type); EG(ret, err);
1482 *f0865ec9SKyle Evans 	/*  EM = Y || maskedSeed || maskedDB */
1483 *f0865ec9SKyle Evans 	maskedseed = &em[1];
1484 *f0865ec9SKyle Evans 	maskeddb   = &em[hlen + 1];
1485 *f0865ec9SKyle Evans 	/* seedMask = MGF(maskedDB, hLen) */
1486 *f0865ec9SKyle Evans 	khlen = (k - hlen - 1);
1487 *f0865ec9SKyle Evans 	MUST_HAVE((khlen < (u32)((u32)0x1 << 16)), ret, err);
1488 *f0865ec9SKyle Evans 	ret = _mgf1(maskeddb, (u16)khlen, seedmask, hlen, mgf_hash_type); EG(ret, err);
1489 *f0865ec9SKyle Evans 	/* Let maskedSeed = seed \xor seedMask */
1490 *f0865ec9SKyle Evans 	for(i = 0; i < hlen; i++){
1491 *f0865ec9SKyle Evans 		seed[i] = (maskedseed[i] ^ seedmask[i]);
1492 *f0865ec9SKyle Evans 	}
1493 *f0865ec9SKyle Evans 	/* dbMask = MGF(seed, k - hLen - 1) */
1494 *f0865ec9SKyle Evans 	MUST_HAVE((khlen <= sizeof(dbmask)), ret, err);
1495 *f0865ec9SKyle Evans 	ret = _mgf1(seed, hlen, dbmask, khlen, mgf_hash_type); EG(ret, err);
1496 *f0865ec9SKyle Evans 	/* Let DB = maskedDB \xor dbMask */
1497 *f0865ec9SKyle Evans 	db = dbmask;
1498 *f0865ec9SKyle Evans 	for(i = 0; i < khlen; i++){
1499 *f0865ec9SKyle Evans 		db[i] = (maskeddb[i] ^ dbmask[i]);
1500 *f0865ec9SKyle Evans 	}
1501 *f0865ec9SKyle Evans 	/* DB = lHash' || PS || 0x01 || M */
1502 *f0865ec9SKyle Evans 	/* NOTE: we try our best to do the following in constant time to
1503 *f0865ec9SKyle Evans 	 * limit padding oracles here (see Manger attacks).
1504 *f0865ec9SKyle Evans 	 */
1505 *f0865ec9SKyle Evans 	/* Y must be != 0 */
1506 *f0865ec9SKyle Evans 	ret = em[0];
1507 *f0865ec9SKyle Evans 	/* Isolate and compare lHash' to lHash */
1508 *f0865ec9SKyle Evans 	ret |= are_equal(&db[0], lhash, hlen, &cmp);
1509 *f0865ec9SKyle Evans 	ret |= ((~cmp) & 0x1);
1510 *f0865ec9SKyle Evans 	/* Find 0x01 separator in constant time */
1511 *f0865ec9SKyle Evans 	pos = 0;
1512 *f0865ec9SKyle Evans 	for(i = hlen; i < khlen; i++){
1513 *f0865ec9SKyle Evans 		u8 r_;
1514 *f0865ec9SKyle Evans 		pos = ((db[i] == 0x01) && (pos == 0)) ? i : pos;
1515 *f0865ec9SKyle Evans 		r_ = (pos == 0) ? db[i] : 0;
1516 *f0865ec9SKyle Evans 		ret |= r_; /* Capture non zero PS */
1517 *f0865ec9SKyle Evans 	}
1518 *f0865ec9SKyle Evans 	pos = (pos == 0) ? pos : (pos + 1);
1519 *f0865ec9SKyle Evans 	/* We get a random value between 2 and k if we have an error so that
1520 *f0865ec9SKyle Evans 	 * we put a random value in pos.
1521 *f0865ec9SKyle Evans 	 */
1522 *f0865ec9SKyle Evans         ret |= get_random((u8*)&i, 4);
1523 *f0865ec9SKyle Evans 	/* Get a random value r for later loop dummy operations */
1524 *f0865ec9SKyle Evans 	ret |= get_random(&r, 1);
1525 *f0865ec9SKyle Evans 	/* Update pos with random value in case of error to progress
1526 *f0865ec9SKyle Evans 	 * nominally with the algorithm
1527 *f0865ec9SKyle Evans 	 */
1528 *f0865ec9SKyle Evans 	pos = (ret) ? ((i % (khlen - hlen)) + hlen) : pos;
1529 *f0865ec9SKyle Evans 	/* Copy the result */
1530 *f0865ec9SKyle Evans 	for(i = hlen; i < khlen; i++){
1531 *f0865ec9SKyle Evans 		u8 r_;
1532 *f0865ec9SKyle Evans 		unsigned int idx;
1533 *f0865ec9SKyle Evans 		/* Replace m by a random value in case of error */
1534 *f0865ec9SKyle Evans 		idx = (i < pos) ? 0x00 : (i - pos);
1535 *f0865ec9SKyle Evans 		r ^= (u8)i;
1536 *f0865ec9SKyle Evans 		r_ = (u8)((u8)(!!ret) * r);
1537 *f0865ec9SKyle Evans 		m[idx] = (db[i] ^ r_);
1538 *f0865ec9SKyle Evans 	}
1539 *f0865ec9SKyle Evans 	(*mlen) = (u16)(k - hlen - 1 - pos);
1540 *f0865ec9SKyle Evans 	/* Hide return value details to avoid information leak */
1541 *f0865ec9SKyle Evans 	ret = -(!!ret);
1542 *f0865ec9SKyle Evans 
1543 *f0865ec9SKyle Evans err:
1544 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1545 *f0865ec9SKyle Evans 	nn_uninit(&c_);
1546 *f0865ec9SKyle Evans 
1547 *f0865ec9SKyle Evans 	return ret;
1548 *f0865ec9SKyle Evans }
1549 *f0865ec9SKyle Evans 
1550 *f0865ec9SKyle Evans /*
1551 *f0865ec9SKyle Evans  * Basic version without much SCA/faults protections.
1552 *f0865ec9SKyle Evans  */
rsaes_oaep_decrypt(const rsa_priv_key * priv,const u8 * c,u32 clen,u8 * m,u32 * mlen,u32 modbits,const u8 * label,u32 label_len,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type)1553 *f0865ec9SKyle Evans int rsaes_oaep_decrypt(const rsa_priv_key *priv, const u8 *c, u32 clen,
1554 *f0865ec9SKyle Evans                        u8 *m, u32 *mlen, u32 modbits,
1555 *f0865ec9SKyle Evans                        const u8 *label, u32 label_len, gen_hash_alg_type gen_hash_type,
1556 *f0865ec9SKyle Evans 		       gen_hash_alg_type mgf_hash_type)
1557 *f0865ec9SKyle Evans {
1558 *f0865ec9SKyle Evans 	return _rsaes_oaep_decrypt(priv, NULL, c, clen, m, mlen, modbits, label, label_len, gen_hash_type, mgf_hash_type);
1559 *f0865ec9SKyle Evans }
1560 *f0865ec9SKyle Evans 
1561 *f0865ec9SKyle Evans /*
1562 *f0865ec9SKyle Evans  * Hardened version with some SCA/faults protections.
1563 *f0865ec9SKyle Evans  */
rsaes_oaep_decrypt_hardened(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * c,u32 clen,u8 * m,u32 * mlen,u32 modbits,const u8 * label,u32 label_len,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type)1564 *f0865ec9SKyle Evans int rsaes_oaep_decrypt_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen,
1565 *f0865ec9SKyle Evans                        u8 *m, u32 *mlen, u32 modbits,
1566 *f0865ec9SKyle Evans                        const u8 *label, u32 label_len, gen_hash_alg_type gen_hash_type,
1567 *f0865ec9SKyle Evans 		       gen_hash_alg_type mgf_hash_type)
1568 *f0865ec9SKyle Evans {
1569 *f0865ec9SKyle Evans 	return _rsaes_oaep_decrypt(priv, pub, c, clen, m, mlen, modbits, label, label_len, gen_hash_type, mgf_hash_type);
1570 *f0865ec9SKyle Evans }
1571 *f0865ec9SKyle Evans 
1572 *f0865ec9SKyle Evans /****************************************************************/
1573 *f0865ec9SKyle Evans /******** Signature schemes *************************************/
1574 *f0865ec9SKyle Evans /* The RSASSA-PKCS1-V1_5-SIGN signature algorithm as described in RFC 8017 section 8.2.1
1575 *f0865ec9SKyle Evans  *
1576 *f0865ec9SKyle Evans  */
_rsassa_pkcs1_v1_5_sign(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * m,u32 mlen,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type)1577 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsassa_pkcs1_v1_5_sign(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen,
1578 *f0865ec9SKyle Evans                            u8 *s, u16 *slen, u32 modbits, gen_hash_alg_type gen_hash_type)
1579 *f0865ec9SKyle Evans {
1580 *f0865ec9SKyle Evans 	int ret;
1581 *f0865ec9SKyle Evans 	u8 *em = s;
1582 *f0865ec9SKyle Evans 	u32 k;
1583 *f0865ec9SKyle Evans 	nn m_, s_;
1584 *f0865ec9SKyle Evans 	m_.magic = s_.magic = WORD(0);
1585 *f0865ec9SKyle Evans 
1586 *f0865ec9SKyle Evans 	/* Checks on sizes */
1587 *f0865ec9SKyle Evans 	MUST_HAVE((slen != NULL), ret, err);
1588 *f0865ec9SKyle Evans 
1589 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1590 *f0865ec9SKyle Evans 
1591 *f0865ec9SKyle Evans 	/* Only accept reasonable sizes */
1592 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1593 *f0865ec9SKyle Evans 	/* Sanity check on size */
1594 *f0865ec9SKyle Evans 	MUST_HAVE(((*slen) >= k), ret, err);
1595 *f0865ec9SKyle Evans 
1596 *f0865ec9SKyle Evans 	/* EM = EMSA-PKCS1-V1_5-ENCODE (M, k) */
1597 *f0865ec9SKyle Evans 	ret = emsa_pkcs1_v1_5_encode(m, mlen, em, (u16)k, gen_hash_type); EG(ret, err);
1598 *f0865ec9SKyle Evans 
1599 *f0865ec9SKyle Evans 	/* m = OS2IP (EM) */
1600 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&m_, em, (u16)k); EG(ret, err);
1601 *f0865ec9SKyle Evans 	/* s = RSASP1 (K, m) */
1602 *f0865ec9SKyle Evans 	if(pub != NULL){
1603 *f0865ec9SKyle Evans 		ret = rsasp1_hardened(priv, pub, &m_, &s_); EG(ret, err);
1604 *f0865ec9SKyle Evans 	}
1605 *f0865ec9SKyle Evans 	else{
1606 *f0865ec9SKyle Evans 		ret = rsasp1(priv, &m_, &s_); EG(ret, err);
1607 *f0865ec9SKyle Evans 	}
1608 *f0865ec9SKyle Evans 	/* S = I2OSP (s, k) */
1609 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&s_, s, (u16)k);
1610 *f0865ec9SKyle Evans 	(*slen) = (u16)k;
1611 *f0865ec9SKyle Evans 
1612 *f0865ec9SKyle Evans err:
1613 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1614 *f0865ec9SKyle Evans 	nn_uninit(&s_);
1615 *f0865ec9SKyle Evans 	/* Zeroify in case of error */
1616 *f0865ec9SKyle Evans 	if(ret && (slen != NULL)){
1617 *f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(s, 0, (*slen)));
1618 *f0865ec9SKyle Evans 	}
1619 *f0865ec9SKyle Evans 
1620 *f0865ec9SKyle Evans 	return ret;
1621 *f0865ec9SKyle Evans }
1622 *f0865ec9SKyle Evans 
1623 *f0865ec9SKyle Evans /*
1624 *f0865ec9SKyle Evans  * Basic version without much SCA/faults protections.
1625 *f0865ec9SKyle Evans  */
rsassa_pkcs1_v1_5_sign(const rsa_priv_key * priv,const u8 * m,u32 mlen,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type)1626 *f0865ec9SKyle Evans int rsassa_pkcs1_v1_5_sign(const rsa_priv_key *priv, const u8 *m, u32 mlen,
1627 *f0865ec9SKyle Evans                            u8 *s, u16 *slen, u32 modbits, gen_hash_alg_type gen_hash_type)
1628 *f0865ec9SKyle Evans {
1629 *f0865ec9SKyle Evans 	return _rsassa_pkcs1_v1_5_sign(priv, NULL, m, mlen, s, slen, modbits, gen_hash_type);
1630 *f0865ec9SKyle Evans }
1631 *f0865ec9SKyle Evans 
1632 *f0865ec9SKyle Evans /*
1633 *f0865ec9SKyle Evans  * Hardened version with some SCA/faults protections.
1634 *f0865ec9SKyle Evans  */
rsassa_pkcs1_v1_5_sign_hardened(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * m,u32 mlen,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type)1635 *f0865ec9SKyle Evans int rsassa_pkcs1_v1_5_sign_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen,
1636 *f0865ec9SKyle Evans                            u8 *s, u16 *slen, u32 modbits, gen_hash_alg_type gen_hash_type)
1637 *f0865ec9SKyle Evans {
1638 *f0865ec9SKyle Evans 	return _rsassa_pkcs1_v1_5_sign(priv, pub, m, mlen, s, slen, modbits, gen_hash_type);
1639 *f0865ec9SKyle Evans }
1640 *f0865ec9SKyle Evans 
1641 *f0865ec9SKyle Evans /* The RSASSA-PKCS1-V1_5-VERIFY verification algorithm as described in RFC 8017 section 8.2.2
1642 *f0865ec9SKyle Evans  *
1643 *f0865ec9SKyle Evans  */
rsassa_pkcs1_v1_5_verify(const rsa_pub_key * pub,const u8 * m,u32 mlen,const u8 * s,u16 slen,u32 modbits,gen_hash_alg_type gen_hash_type)1644 *f0865ec9SKyle Evans int rsassa_pkcs1_v1_5_verify(const rsa_pub_key *pub, const u8 *m, u32 mlen,
1645 *f0865ec9SKyle Evans                              const u8 *s, u16 slen, u32 modbits, gen_hash_alg_type gen_hash_type)
1646 *f0865ec9SKyle Evans {
1647 *f0865ec9SKyle Evans 	int ret, cmp;
1648 *f0865ec9SKyle Evans 	/* Get a large enough buffer to hold the result */
1649 *f0865ec9SKyle Evans         /*
1650 *f0865ec9SKyle Evans          * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here.
1651 *f0865ec9SKyle Evans          */
1652 *f0865ec9SKyle Evans 	u8 em[NN_USABLE_MAX_BYTE_LEN];
1653 *f0865ec9SKyle Evans 	u8 em_[NN_USABLE_MAX_BYTE_LEN];
1654 *f0865ec9SKyle Evans 	u32 k;
1655 *f0865ec9SKyle Evans 	nn m_, s_;
1656 *f0865ec9SKyle Evans 	m_.magic = s_.magic = WORD(0);
1657 *f0865ec9SKyle Evans 
1658 *f0865ec9SKyle Evans 	/* Zeroize local variables */
1659 *f0865ec9SKyle Evans 	ret = local_memset(em, 0, sizeof(em)); EG(ret, err);
1660 *f0865ec9SKyle Evans 	ret = local_memset(em_, 0, sizeof(em_)); EG(ret, err);
1661 *f0865ec9SKyle Evans 
1662 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1663 *f0865ec9SKyle Evans 	/* Only accept reasonable sizes */
1664 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1665 *f0865ec9SKyle Evans 
1666 *f0865ec9SKyle Evans 	/* Length checking: If the length of the signature S is not k
1667 *f0865ec9SKyle Evans          * octets, output "invalid signature" and stop.
1668 *f0865ec9SKyle Evans 	 */
1669 *f0865ec9SKyle Evans 	MUST_HAVE(((u16)k == slen), ret, err);
1670 *f0865ec9SKyle Evans 
1671 *f0865ec9SKyle Evans 	/* s = OS2IP (S) */
1672 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&s_, s, slen); EG(ret, err);
1673 *f0865ec9SKyle Evans 	/* m = RSAVP1 ((n, e), s) */
1674 *f0865ec9SKyle Evans 	ret = rsavp1(pub, &s_, &m_); EG(ret, err);
1675 *f0865ec9SKyle Evans 	/* EM = I2OSP (m, k) */
1676 *f0865ec9SKyle Evans 	MUST_HAVE((slen <= sizeof(em)), ret, err);
1677 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&m_, em, slen); EG(ret, err);
1678 *f0865ec9SKyle Evans 	/* EM' = EMSA-PKCS1-V1_5-ENCODE (M, k) */
1679 *f0865ec9SKyle Evans 	MUST_HAVE((k <= sizeof(em_)), ret, err);
1680 *f0865ec9SKyle Evans 	ret = emsa_pkcs1_v1_5_encode(m, mlen, em_, (u16)k, gen_hash_type); EG(ret, err);
1681 *f0865ec9SKyle Evans 
1682 *f0865ec9SKyle Evans 	/* Compare */
1683 *f0865ec9SKyle Evans 	ret = are_equal(em, em_, (u16)k, &cmp); EG(ret, err);
1684 *f0865ec9SKyle Evans 	if(!cmp){
1685 *f0865ec9SKyle Evans 		ret = -1;
1686 *f0865ec9SKyle Evans 	}
1687 *f0865ec9SKyle Evans err:
1688 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1689 *f0865ec9SKyle Evans 	nn_uninit(&s_);
1690 *f0865ec9SKyle Evans 
1691 *f0865ec9SKyle Evans 	return ret;
1692 *f0865ec9SKyle Evans }
1693 *f0865ec9SKyle Evans 
1694 *f0865ec9SKyle Evans /* The RSASSA-PSS-SIGN signature algorithm as described in RFC 8017 section 8.1.1
1695 *f0865ec9SKyle Evans  *
1696 *f0865ec9SKyle Evans  */
_rsassa_pss_sign(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * m,u32 mlen,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type,u32 saltlen,const u8 * forced_salt)1697 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsassa_pss_sign(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen,
1698 *f0865ec9SKyle Evans                     u8 *s, u16 *slen, u32 modbits,
1699 *f0865ec9SKyle Evans 		    gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type,
1700 *f0865ec9SKyle Evans                     u32 saltlen, const u8 *forced_salt)
1701 *f0865ec9SKyle Evans {
1702 *f0865ec9SKyle Evans 	int ret;
1703 *f0865ec9SKyle Evans 	u8 *em = s;
1704 *f0865ec9SKyle Evans 	u16 emsize;
1705 *f0865ec9SKyle Evans 	u32 k;
1706 *f0865ec9SKyle Evans 	nn m_, s_;
1707 *f0865ec9SKyle Evans 	m_.magic = s_.magic = WORD(0);
1708 *f0865ec9SKyle Evans 
1709 *f0865ec9SKyle Evans 	MUST_HAVE((slen != NULL), ret, err);
1710 *f0865ec9SKyle Evans 
1711 *f0865ec9SKyle Evans 	MUST_HAVE((modbits > 1), ret, err);
1712 *f0865ec9SKyle Evans 
1713 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1714 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1715 *f0865ec9SKyle Evans 
1716 *f0865ec9SKyle Evans 	/* Sanity check on size */
1717 *f0865ec9SKyle Evans 	MUST_HAVE(((*slen) >= k), ret, err);
1718 *f0865ec9SKyle Evans 
1719 *f0865ec9SKyle Evans 	/* EM = EMSA-PSS-ENCODE (M, modBits - 1) */
1720 *f0865ec9SKyle Evans 	emsize = (*slen);
1721 *f0865ec9SKyle Evans 	ret = emsa_pss_encode(m, mlen, em, (modbits - 1), &emsize, gen_hash_type, mgf_hash_type, saltlen, forced_salt); EG(ret, err);
1722 *f0865ec9SKyle Evans 
1723 *f0865ec9SKyle Evans 	/* Note that the octet length of EM will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise */
1724 *f0865ec9SKyle Evans 	MUST_HAVE(emsize == BYTECEIL(modbits - 1), ret, err);
1725 *f0865ec9SKyle Evans 
1726 *f0865ec9SKyle Evans 	/* m = OS2IP (EM) */
1727 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&m_, em, (u16)emsize); EG(ret, err);
1728 *f0865ec9SKyle Evans 	/* s = RSASP1 (K, m) */
1729 *f0865ec9SKyle Evans 	if(pub != NULL){
1730 *f0865ec9SKyle Evans 		ret = rsasp1_hardened(priv, pub, &m_, &s_); EG(ret, err);
1731 *f0865ec9SKyle Evans 	}
1732 *f0865ec9SKyle Evans 	else{
1733 *f0865ec9SKyle Evans 		ret = rsasp1(priv, &m_, &s_); EG(ret, err);
1734 *f0865ec9SKyle Evans 	}
1735 *f0865ec9SKyle Evans 	/* S = I2OSP (s, k) */
1736 *f0865ec9SKyle Evans 	MUST_HAVE((k < ((u32)0x1 << 16)), ret, err);
1737 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&s_, s, (u16)k);
1738 *f0865ec9SKyle Evans 	(*slen) = (u16)k;
1739 *f0865ec9SKyle Evans 
1740 *f0865ec9SKyle Evans err:
1741 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1742 *f0865ec9SKyle Evans 	nn_uninit(&s_);
1743 *f0865ec9SKyle Evans 	/* Zeroify in case of error */
1744 *f0865ec9SKyle Evans 	if(ret && (slen != NULL)){
1745 *f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(s, 0, (*slen)));
1746 *f0865ec9SKyle Evans 	}
1747 *f0865ec9SKyle Evans 
1748 *f0865ec9SKyle Evans 	return ret;
1749 *f0865ec9SKyle Evans }
1750 *f0865ec9SKyle Evans 
1751 *f0865ec9SKyle Evans /*
1752 *f0865ec9SKyle Evans  * Basic version without much SCA/faults protections.
1753 *f0865ec9SKyle Evans  */
rsassa_pss_sign(const rsa_priv_key * priv,const u8 * m,u32 mlen,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type,u32 saltlen,const u8 * forced_salt)1754 *f0865ec9SKyle Evans int rsassa_pss_sign(const rsa_priv_key *priv, const u8 *m, u32 mlen,
1755 *f0865ec9SKyle Evans                     u8 *s, u16 *slen, u32 modbits,
1756 *f0865ec9SKyle Evans 		    gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type,
1757 *f0865ec9SKyle Evans                     u32 saltlen, const u8 *forced_salt)
1758 *f0865ec9SKyle Evans {
1759 *f0865ec9SKyle Evans 	return _rsassa_pss_sign(priv, NULL, m, mlen, s, slen, modbits, gen_hash_type, mgf_hash_type, saltlen, forced_salt);
1760 *f0865ec9SKyle Evans }
1761 *f0865ec9SKyle Evans 
1762 *f0865ec9SKyle Evans /*
1763 *f0865ec9SKyle Evans  * Hardened version with some SCA/faults protections.
1764 *f0865ec9SKyle Evans  */
rsassa_pss_sign_hardened(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * m,u32 mlen,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type,u32 saltlen,const u8 * forced_salt)1765 *f0865ec9SKyle Evans int rsassa_pss_sign_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen,
1766 *f0865ec9SKyle Evans                     u8 *s, u16 *slen, u32 modbits,
1767 *f0865ec9SKyle Evans 		    gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type,
1768 *f0865ec9SKyle Evans                     u32 saltlen, const u8 *forced_salt)
1769 *f0865ec9SKyle Evans {
1770 *f0865ec9SKyle Evans 	return _rsassa_pss_sign(priv, pub, m, mlen, s, slen, modbits, gen_hash_type, mgf_hash_type, saltlen, forced_salt);
1771 *f0865ec9SKyle Evans }
1772 *f0865ec9SKyle Evans 
1773 *f0865ec9SKyle Evans 
1774 *f0865ec9SKyle Evans /* The RSASSA-PSS-VERIFY verification algorithm as described in RFC 8017 section 8.1.2
1775 *f0865ec9SKyle Evans  *
1776 *f0865ec9SKyle Evans  */
rsassa_pss_verify(const rsa_pub_key * pub,const u8 * m,u32 mlen,const u8 * s,u16 slen,u32 modbits,gen_hash_alg_type gen_hash_type,gen_hash_alg_type mgf_hash_type,u32 saltlen)1777 *f0865ec9SKyle Evans int rsassa_pss_verify(const rsa_pub_key *pub, const u8 *m, u32 mlen,
1778 *f0865ec9SKyle Evans                       const u8 *s, u16 slen, u32 modbits,
1779 *f0865ec9SKyle Evans                       gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type,
1780 *f0865ec9SKyle Evans 		      u32 saltlen)
1781 *f0865ec9SKyle Evans {
1782 *f0865ec9SKyle Evans 	int ret;
1783 *f0865ec9SKyle Evans 	/* Get a large enough buffer to hold the result */
1784 *f0865ec9SKyle Evans         /*
1785 *f0865ec9SKyle Evans          * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here.
1786 *f0865ec9SKyle Evans          */
1787 *f0865ec9SKyle Evans 	u8 em[NN_USABLE_MAX_BYTE_LEN];
1788 *f0865ec9SKyle Evans 	u16 emlen;
1789 *f0865ec9SKyle Evans 	u32 k;
1790 *f0865ec9SKyle Evans 	nn m_, s_;
1791 *f0865ec9SKyle Evans 	m_.magic = s_.magic = WORD(0);
1792 *f0865ec9SKyle Evans 
1793 *f0865ec9SKyle Evans 	/* Zeroize local variables */
1794 *f0865ec9SKyle Evans 	ret = local_memset(em, 0, sizeof(em)); EG(ret, err);
1795 *f0865ec9SKyle Evans 
1796 *f0865ec9SKyle Evans 	MUST_HAVE((modbits > 1), ret, err);
1797 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1798 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1799 *f0865ec9SKyle Evans 
1800 *f0865ec9SKyle Evans 	/* s = OS2IP (S) */
1801 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&s_, s, slen); EG(ret, err);
1802 *f0865ec9SKyle Evans 	/* m = RSAVP1 ((n, e), s) */
1803 *f0865ec9SKyle Evans 	ret = rsavp1(pub, &s_, &m_); EG(ret, err);
1804 *f0865ec9SKyle Evans 	/* emLen = \ceil ((modBits - 1)/8) */
1805 *f0865ec9SKyle Evans 	MUST_HAVE((((modbits - 1) / 8) + 1) < (u32)((u32)0x1 << 16), ret, err);
1806 *f0865ec9SKyle Evans 	emlen = (((modbits - 1) % 8) == 0) ? (u16)((modbits - 1) / 8) : (u16)(((modbits - 1) / 8) + 1);
1807 *f0865ec9SKyle Evans 
1808 *f0865ec9SKyle Evans 	/* Note that emLen will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise */
1809 *f0865ec9SKyle Evans 	MUST_HAVE(emlen == BYTECEIL(modbits - 1), ret, err);
1810 *f0865ec9SKyle Evans 
1811 *f0865ec9SKyle Evans 	/* EM = I2OSP (m, emLen) */
1812 *f0865ec9SKyle Evans 	MUST_HAVE((emlen <= sizeof(em)), ret, err);
1813 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&m_, em, (u16)emlen); EG(ret, err);
1814 *f0865ec9SKyle Evans 	/*  Result = EMSA-PSS-VERIFY (M, EM, modBits - 1) */
1815 *f0865ec9SKyle Evans 	ret = emsa_pss_verify(m, mlen, em, (modbits - 1), emlen, gen_hash_type, mgf_hash_type, saltlen);
1816 *f0865ec9SKyle Evans 
1817 *f0865ec9SKyle Evans err:
1818 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1819 *f0865ec9SKyle Evans 	nn_uninit(&s_);
1820 *f0865ec9SKyle Evans 
1821 *f0865ec9SKyle Evans 	return ret;
1822 *f0865ec9SKyle Evans }
1823 *f0865ec9SKyle Evans 
1824 *f0865ec9SKyle Evans /* The RSA signature algorithm using ISO/IEC 9796-2 padding scheme 1.
1825 *f0865ec9SKyle Evans  * This is a signature with recovery.
1826 *f0865ec9SKyle Evans  *
1827 *f0865ec9SKyle Evans  * XXX: beware that this scheme is here for completeness, but is considered fragile
1828 *f0865ec9SKyle Evans  * since practical attacks exist when the hash function is of relatively "small" size
1829 *f0865ec9SKyle Evans  * (see http://www.crypto-uni.lu/jscoron/publications/iso97962joc.pdf).
1830 *f0865ec9SKyle Evans  *
1831 *f0865ec9SKyle Evans  * The ISO/IEC 9796-2 is also described in EMV Book 2 in the A.2.1 section:
1832 *f0865ec9SKyle Evans  * "Digital Signature Scheme Giving Message Recovery".
1833 *f0865ec9SKyle Evans  *
1834 *f0865ec9SKyle Evans  */
_rsa_iso9796_2_sign_recover(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * m,u32 mlen,u32 * m1len,u32 * m2len,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type)1835 *f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsa_iso9796_2_sign_recover(const rsa_priv_key *priv, const rsa_pub_key *pub,
1836 *f0865ec9SKyle Evans 								 const u8 *m, u32 mlen, u32 *m1len, u32 *m2len, u8 *s, u16 *slen,
1837 *f0865ec9SKyle Evans 								 u32 modbits, gen_hash_alg_type gen_hash_type)
1838 *f0865ec9SKyle Evans {
1839 *f0865ec9SKyle Evans 	int ret;
1840 *f0865ec9SKyle Evans 	u32 k, m1len_, m2len_;
1841 *f0865ec9SKyle Evans 	u8 hlen, block_size;
1842 *f0865ec9SKyle Evans 	gen_hash_context hctx;
1843 *f0865ec9SKyle Evans 	nn m_, s_;
1844 *f0865ec9SKyle Evans 	m_.magic = s_.magic = WORD(0);
1845 *f0865ec9SKyle Evans 
1846 *f0865ec9SKyle Evans 	MUST_HAVE((priv != NULL) && (m != NULL), ret, err);
1847 *f0865ec9SKyle Evans 
1848 *f0865ec9SKyle Evans 	MUST_HAVE((slen != NULL), ret, err);
1849 *f0865ec9SKyle Evans 
1850 *f0865ec9SKyle Evans 	MUST_HAVE((modbits > 1), ret, err);
1851 *f0865ec9SKyle Evans 
1852 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1853 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1854 *f0865ec9SKyle Evans 
1855 *f0865ec9SKyle Evans 	/* Get hash parameters */
1856 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err);
1857 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
1858 *f0865ec9SKyle Evans 
1859 *f0865ec9SKyle Evans 	/* Sanity check on sizes */
1860 *f0865ec9SKyle Evans 	MUST_HAVE(((*slen) >= k), ret, err);
1861 *f0865ec9SKyle Evans 	MUST_HAVE(k >= (u32)(2 + hlen), ret, err);
1862 *f0865ec9SKyle Evans 
1863 *f0865ec9SKyle Evans 	/* Compute our recoverable and non-recoverable parts */
1864 *f0865ec9SKyle Evans 	m1len_ = (mlen >= (k - 2 - hlen)) ? (k - 2 - hlen) : mlen;
1865 *f0865ec9SKyle Evans 	m2len_ = (mlen - m1len_);
1866 *f0865ec9SKyle Evans 
1867 *f0865ec9SKyle Evans 	/* Now hash the message */
1868 *f0865ec9SKyle Evans 	ret = gen_hash_init(&hctx, gen_hash_type); EG(ret, err);
1869 *f0865ec9SKyle Evans 	ret = gen_hash_update(&hctx, m, mlen, gen_hash_type); EG(ret, err);
1870 *f0865ec9SKyle Evans 	ret = gen_hash_final(&hctx, &s[k - 1 - hlen], gen_hash_type); EG(ret, err);
1871 *f0865ec9SKyle Evans 
1872 *f0865ec9SKyle Evans 	/* Put M1 */
1873 *f0865ec9SKyle Evans 	ret = local_memcpy(&s[1], m, m1len_); EG(ret, err);
1874 *f0865ec9SKyle Evans 	if(m1len != NULL){
1875 *f0865ec9SKyle Evans 		(*m1len) = m1len_;
1876 *f0865ec9SKyle Evans 	}
1877 *f0865ec9SKyle Evans 	if(m2len != NULL){
1878 *f0865ec9SKyle Evans 		(*m2len) = m2len_;
1879 *f0865ec9SKyle Evans 	}
1880 *f0865ec9SKyle Evans 
1881 *f0865ec9SKyle Evans 	/* Put the constants */
1882 *f0865ec9SKyle Evans 	s[0]     = 0x6a;
1883 *f0865ec9SKyle Evans 	s[k - 1] = 0xbc;
1884 *f0865ec9SKyle Evans 
1885 *f0865ec9SKyle Evans 	/* m = OS2IP (X) */
1886 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&m_, s, k); EG(ret, err);
1887 *f0865ec9SKyle Evans 	/* s = RSASP1 (K, m) */
1888 *f0865ec9SKyle Evans 	if(pub != NULL){
1889 *f0865ec9SKyle Evans 		ret = rsasp1_hardened(priv, pub, &m_, &s_); EG(ret, err);
1890 *f0865ec9SKyle Evans 	}
1891 *f0865ec9SKyle Evans 	else{
1892 *f0865ec9SKyle Evans 		ret = rsasp1(priv, &m_, &s_); EG(ret, err);
1893 *f0865ec9SKyle Evans 	}
1894 *f0865ec9SKyle Evans 	/* S = I2OSP (s, k) */
1895 *f0865ec9SKyle Evans 	MUST_HAVE((k < ((u32)0x1 << 16)), ret, err);
1896 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&s_, s, (u16)k);
1897 *f0865ec9SKyle Evans 	(*slen) = (u16)k;
1898 *f0865ec9SKyle Evans 
1899 *f0865ec9SKyle Evans err:
1900 *f0865ec9SKyle Evans 	nn_uninit(&m_);
1901 *f0865ec9SKyle Evans 	nn_uninit(&s_);
1902 *f0865ec9SKyle Evans 
1903 *f0865ec9SKyle Evans 	if(ret && (m1len != 0)){
1904 *f0865ec9SKyle Evans 		(*m1len) = 0;
1905 *f0865ec9SKyle Evans 	}
1906 *f0865ec9SKyle Evans 	if(ret && (m2len != 0)){
1907 *f0865ec9SKyle Evans 		(*m2len) = 0;
1908 *f0865ec9SKyle Evans 	}
1909 *f0865ec9SKyle Evans 
1910 *f0865ec9SKyle Evans 	return ret;
1911 *f0865ec9SKyle Evans }
1912 *f0865ec9SKyle Evans 
1913 *f0865ec9SKyle Evans /*
1914 *f0865ec9SKyle Evans  * Basic version without much SCA/faults protections.
1915 *f0865ec9SKyle Evans  */
rsa_iso9796_2_sign_recover(const rsa_priv_key * priv,const u8 * m,u32 mlen,u32 * m1len,u32 * m2len,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type)1916 *f0865ec9SKyle Evans int rsa_iso9796_2_sign_recover(const rsa_priv_key *priv, const u8 *m, u32 mlen, u32 *m1len,
1917 *f0865ec9SKyle Evans 			       u32 *m2len, u8 *s, u16 *slen,
1918 *f0865ec9SKyle Evans 			       u32 modbits, gen_hash_alg_type gen_hash_type)
1919 *f0865ec9SKyle Evans {
1920 *f0865ec9SKyle Evans 	return _rsa_iso9796_2_sign_recover(priv, NULL, m, mlen, m1len, m2len, s, slen, modbits, gen_hash_type);
1921 *f0865ec9SKyle Evans }
1922 *f0865ec9SKyle Evans 
1923 *f0865ec9SKyle Evans /*
1924 *f0865ec9SKyle Evans  * Hardened version with some SCA/faults protections.
1925 *f0865ec9SKyle Evans  */
rsa_iso9796_2_sign_recover_hardened(const rsa_priv_key * priv,const rsa_pub_key * pub,const u8 * m,u32 mlen,u32 * m1len,u32 * m2len,u8 * s,u16 * slen,u32 modbits,gen_hash_alg_type gen_hash_type)1926 *f0865ec9SKyle Evans int rsa_iso9796_2_sign_recover_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub,
1927 *f0865ec9SKyle Evans 				        const u8 *m, u32 mlen, u32 *m1len, u32 *m2len, u8 *s, u16 *slen,
1928 *f0865ec9SKyle Evans 				        u32 modbits, gen_hash_alg_type gen_hash_type)
1929 *f0865ec9SKyle Evans {
1930 *f0865ec9SKyle Evans 	return _rsa_iso9796_2_sign_recover(priv, pub, m, mlen, m1len, m2len, s, slen, modbits, gen_hash_type);
1931 *f0865ec9SKyle Evans }
1932 *f0865ec9SKyle Evans 
1933 *f0865ec9SKyle Evans /* The RSA verification algorithm using ISO/IEC 9796-2 padding scheme 1.
1934 *f0865ec9SKyle Evans  * This is a verification with recovery.
1935 *f0865ec9SKyle Evans  *
1936 *f0865ec9SKyle Evans  * XXX: beware that this scheme is here for completeness, but is considered fragile
1937 *f0865ec9SKyle Evans  * since practical attacks exist when the hash function is of relatively "small" size
1938 *f0865ec9SKyle Evans  * (see http://www.crypto-uni.lu/jscoron/publications/iso97962joc.pdf).
1939 *f0865ec9SKyle Evans  *
1940 *f0865ec9SKyle Evans  * The ISO/IEC 9796-2 is also described in EMV Book 2 in the A.2.1 section:
1941 *f0865ec9SKyle Evans  * "Digital Signature Scheme Giving Message Recovery".
1942 *f0865ec9SKyle Evans  *
1943 *f0865ec9SKyle Evans  */
rsa_iso9796_2_verify_recover(const rsa_pub_key * pub,const u8 * m2,u32 m2len,u8 * m1,u32 * m1len,const u8 * s,u16 slen,u32 modbits,gen_hash_alg_type gen_hash_type)1944 *f0865ec9SKyle Evans int rsa_iso9796_2_verify_recover(const rsa_pub_key *pub, const u8 *m2, u32 m2len, u8 *m1, u32 *m1len,
1945 *f0865ec9SKyle Evans                                  const u8 *s, u16 slen, u32 modbits, gen_hash_alg_type gen_hash_type)
1946 *f0865ec9SKyle Evans {
1947 *f0865ec9SKyle Evans 	int ret, cmp;
1948 *f0865ec9SKyle Evans 	/* Get a large enough buffer to hold the result */
1949 *f0865ec9SKyle Evans         /*
1950 *f0865ec9SKyle Evans          * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here.
1951 *f0865ec9SKyle Evans          */
1952 *f0865ec9SKyle Evans 	u8 X[NN_USABLE_MAX_BYTE_LEN];
1953 *f0865ec9SKyle Evans 	u8 H[MAX_DIGEST_SIZE];
1954 *f0865ec9SKyle Evans 	u32 k, m1len_;
1955 *f0865ec9SKyle Evans 	u8 hlen, block_size;
1956 *f0865ec9SKyle Evans 	gen_hash_context hctx;
1957 *f0865ec9SKyle Evans 	nn m_, s_;
1958 *f0865ec9SKyle Evans 	m_.magic = s_.magic = WORD(0);
1959 *f0865ec9SKyle Evans 
1960 *f0865ec9SKyle Evans 	MUST_HAVE((pub != NULL) && (m2 != NULL), ret, err);
1961 *f0865ec9SKyle Evans 
1962 *f0865ec9SKyle Evans 	/* Zeroize local variables */
1963 *f0865ec9SKyle Evans 	ret = local_memset(X, 0, sizeof(X)); EG(ret, err);
1964 *f0865ec9SKyle Evans 	ret = local_memset(H, 0, sizeof(H)); EG(ret, err);
1965 *f0865ec9SKyle Evans 
1966 *f0865ec9SKyle Evans 	k = BYTECEIL(modbits);
1967 *f0865ec9SKyle Evans 	/* Only accept reasonable sizes */
1968 *f0865ec9SKyle Evans 	MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err);
1969 *f0865ec9SKyle Evans 
1970 *f0865ec9SKyle Evans 	ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err);
1971 *f0865ec9SKyle Evans 	MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
1972 *f0865ec9SKyle Evans 
1973 *f0865ec9SKyle Evans 	/* Length checking: If the length of the signature S is not k
1974 *f0865ec9SKyle Evans          * octets, output "invalid signature" and stop.
1975 *f0865ec9SKyle Evans 	 */
1976 *f0865ec9SKyle Evans 	MUST_HAVE(((u16)k == slen), ret, err);
1977 *f0865ec9SKyle Evans 	MUST_HAVE((slen >= (hlen + 2)), ret, err);
1978 *f0865ec9SKyle Evans 	m1len_ = (u32)(slen - (hlen + 2));
1979 *f0865ec9SKyle Evans 
1980 *f0865ec9SKyle Evans 	/* s = OS2IP (S) */
1981 *f0865ec9SKyle Evans 	ret = rsa_os2ip(&s_, s, slen); EG(ret, err);
1982 *f0865ec9SKyle Evans 	/* m = RSAVP1 ((n, e), s) */
1983 *f0865ec9SKyle Evans 	ret = rsavp1(pub, &s_, &m_); EG(ret, err);
1984 *f0865ec9SKyle Evans 	/* EM = I2OSP (m, k) */
1985 *f0865ec9SKyle Evans 	MUST_HAVE((slen <= sizeof(X)), ret, err);
1986 *f0865ec9SKyle Evans 	ret = rsa_i2osp(&m_, X, slen); EG(ret, err);
1987 *f0865ec9SKyle Evans 
1988 *f0865ec9SKyle Evans 	/* Split the message in B || m1 || H || E with
1989 *f0865ec9SKyle Evans 	 * B = '6A', E = 'BC', and H the hash value */
1990 *f0865ec9SKyle Evans 	if(m1len != NULL){
1991 *f0865ec9SKyle Evans 		MUST_HAVE((*m1len) >= m1len_, ret, err);
1992 *f0865ec9SKyle Evans 		(*m1len) = m1len_;
1993 *f0865ec9SKyle Evans 	}
1994 *f0865ec9SKyle Evans 	if((X[0] != 0x6a) || (X[slen - 1] != 0xbc)){
1995 *f0865ec9SKyle Evans 		ret = -1;
1996 *f0865ec9SKyle Evans 		goto err;
1997 *f0865ec9SKyle Evans 	}
1998 *f0865ec9SKyle Evans 
1999 *f0865ec9SKyle Evans 	/* Compute the hash of m1 || m2 */
2000 *f0865ec9SKyle Evans 	ret = gen_hash_init(&hctx, gen_hash_type); EG(ret, err);
2001 *f0865ec9SKyle Evans 	ret = gen_hash_update(&hctx, &X[1], m1len_, gen_hash_type); EG(ret, err);
2002 *f0865ec9SKyle Evans 	ret = gen_hash_update(&hctx, m2, m2len, gen_hash_type); EG(ret, err);
2003 *f0865ec9SKyle Evans 	ret = gen_hash_final(&hctx, H, gen_hash_type); EG(ret, err);
2004 *f0865ec9SKyle Evans 
2005 *f0865ec9SKyle Evans 	/* Compare */
2006 *f0865ec9SKyle Evans 	ret = are_equal(H, &X[1 + m1len_], (u16)hlen, &cmp); EG(ret, err);
2007 *f0865ec9SKyle Evans 	if(!cmp){
2008 *f0865ec9SKyle Evans 		ret = -1;
2009 *f0865ec9SKyle Evans 	}
2010 *f0865ec9SKyle Evans 	/* If comparison is OK, copy data */
2011 *f0865ec9SKyle Evans 	if(m1 != NULL){
2012 *f0865ec9SKyle Evans 		MUST_HAVE((m1len != NULL), ret, err);
2013 *f0865ec9SKyle Evans 		ret = local_memcpy(m1, &X[1], (*m1len)); EG(ret, err);
2014 *f0865ec9SKyle Evans 	}
2015 *f0865ec9SKyle Evans 
2016 *f0865ec9SKyle Evans err:
2017 *f0865ec9SKyle Evans 	nn_uninit(&m_);
2018 *f0865ec9SKyle Evans 	nn_uninit(&s_);
2019 *f0865ec9SKyle Evans 
2020 *f0865ec9SKyle Evans 	if(ret && (m1len != 0)){
2021 *f0865ec9SKyle Evans 		(*m1len) = 0;
2022 *f0865ec9SKyle Evans 	}
2023 *f0865ec9SKyle Evans 
2024 *f0865ec9SKyle Evans 	return ret;
2025 *f0865ec9SKyle Evans }
2026 *f0865ec9SKyle Evans 
2027 *f0865ec9SKyle Evans #ifdef RSA
2028 *f0865ec9SKyle Evans /* RSA PKCS#1 test vectors taken from:
2029 *f0865ec9SKyle Evans  *     https://github.com/bdauvergne/python-pkcs1/tree/master/tests/data
2030 *f0865ec9SKyle Evans  */
2031 *f0865ec9SKyle Evans #include "rsa_pkcs1_tests.h"
2032 *f0865ec9SKyle Evans 
main(int argc,char * argv[])2033 *f0865ec9SKyle Evans int main(int argc, char *argv[])
2034 *f0865ec9SKyle Evans {
2035 *f0865ec9SKyle Evans 	int ret = 0;
2036 *f0865ec9SKyle Evans 	FORCE_USED_VAR(argc);
2037 *f0865ec9SKyle Evans 	FORCE_USED_VAR(argv);
2038 *f0865ec9SKyle Evans 
2039 *f0865ec9SKyle Evans 	/* Sanity check on size for RSA.
2040 *f0865ec9SKyle Evans 	 * NOTE: the double parentheses are here to handle -Wunreachable-code
2041 *f0865ec9SKyle Evans 	 */
2042 *f0865ec9SKyle Evans 	if((NN_USABLE_MAX_BIT_LEN) < (4096)){
2043 *f0865ec9SKyle Evans 		ext_printf("Error: you seem to have compiled libecc with usable NN size < 4096, not suitable for RSA.\n");
2044 *f0865ec9SKyle Evans 		ext_printf("  => Please recompile libecc with EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\"\n");
2045 *f0865ec9SKyle Evans 		ext_printf("     This will increase usable NN for proper RSA up to 4096 bits.\n");
2046 *f0865ec9SKyle Evans 		ext_printf("     Then recompile the current examples with the same EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\" flag and execute again!\n");
2047 *f0865ec9SKyle Evans 		/* NOTE: ret = 0 here to pass self tests even if the library is not compatible */
2048 *f0865ec9SKyle Evans 		ret = 0;
2049 *f0865ec9SKyle Evans 		goto err;
2050 *f0865ec9SKyle Evans 	}
2051 *f0865ec9SKyle Evans 
2052 *f0865ec9SKyle Evans 	ret = perform_rsa_tests(all_rsa_tests, sizeof(all_rsa_tests) / sizeof(rsa_test*));
2053 *f0865ec9SKyle Evans 
2054 *f0865ec9SKyle Evans err:
2055 *f0865ec9SKyle Evans 	return ret;
2056 *f0865ec9SKyle Evans }
2057 *f0865ec9SKyle Evans #endif
2058