xref: /freebsd/contrib/bearssl/src/rsa/rsa_i15_modulus.c (revision cc9e6590773dba57440750c124173ed531349a06)
10957b409SSimon J. Gerraty /*
20957b409SSimon J. Gerraty  * Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
30957b409SSimon J. Gerraty  *
40957b409SSimon J. Gerraty  * Permission is hereby granted, free of charge, to any person obtaining
50957b409SSimon J. Gerraty  * a copy of this software and associated documentation files (the
60957b409SSimon J. Gerraty  * "Software"), to deal in the Software without restriction, including
70957b409SSimon J. Gerraty  * without limitation the rights to use, copy, modify, merge, publish,
80957b409SSimon J. Gerraty  * distribute, sublicense, and/or sell copies of the Software, and to
90957b409SSimon J. Gerraty  * permit persons to whom the Software is furnished to do so, subject to
100957b409SSimon J. Gerraty  * the following conditions:
110957b409SSimon J. Gerraty  *
120957b409SSimon J. Gerraty  * The above copyright notice and this permission notice shall be
130957b409SSimon J. Gerraty  * included in all copies or substantial portions of the Software.
140957b409SSimon J. Gerraty  *
150957b409SSimon J. Gerraty  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
160957b409SSimon J. Gerraty  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
170957b409SSimon J. Gerraty  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
180957b409SSimon J. Gerraty  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
190957b409SSimon J. Gerraty  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
200957b409SSimon J. Gerraty  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
210957b409SSimon J. Gerraty  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
220957b409SSimon J. Gerraty  * SOFTWARE.
230957b409SSimon J. Gerraty  */
240957b409SSimon J. Gerraty 
250957b409SSimon J. Gerraty #include "inner.h"
260957b409SSimon J. Gerraty 
270957b409SSimon J. Gerraty /* see bearssl_rsa.h */
280957b409SSimon J. Gerraty size_t
br_rsa_i15_compute_modulus(void * n,const br_rsa_private_key * sk)290957b409SSimon J. Gerraty br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk)
300957b409SSimon J. Gerraty {
31*cc9e6590SSimon J. Gerraty 	uint16_t tmp[4 * (((BR_MAX_RSA_SIZE / 2) + 14) / 15) + 5];
320957b409SSimon J. Gerraty 	uint16_t *t, *p, *q;
330957b409SSimon J. Gerraty 	const unsigned char *pbuf, *qbuf;
340957b409SSimon J. Gerraty 	size_t nlen, plen, qlen, tlen;
350957b409SSimon J. Gerraty 
360957b409SSimon J. Gerraty 	/*
370957b409SSimon J. Gerraty 	 * Compute actual byte and lengths for p and q.
380957b409SSimon J. Gerraty 	 */
390957b409SSimon J. Gerraty 	pbuf = sk->p;
400957b409SSimon J. Gerraty 	plen = sk->plen;
410957b409SSimon J. Gerraty 	while (plen > 0 && *pbuf == 0) {
420957b409SSimon J. Gerraty 		pbuf ++;
430957b409SSimon J. Gerraty 		plen --;
440957b409SSimon J. Gerraty 	}
450957b409SSimon J. Gerraty 	qbuf = sk->q;
460957b409SSimon J. Gerraty 	qlen = sk->qlen;
470957b409SSimon J. Gerraty 	while (qlen > 0 && *qbuf == 0) {
480957b409SSimon J. Gerraty 		qbuf ++;
490957b409SSimon J. Gerraty 		qlen --;
500957b409SSimon J. Gerraty 	}
510957b409SSimon J. Gerraty 
520957b409SSimon J. Gerraty 	t = tmp;
530957b409SSimon J. Gerraty 	tlen = (sizeof tmp) / (sizeof tmp[0]);
540957b409SSimon J. Gerraty 
550957b409SSimon J. Gerraty 	/*
560957b409SSimon J. Gerraty 	 * Decode p.
570957b409SSimon J. Gerraty 	 */
580957b409SSimon J. Gerraty 	if ((15 * tlen) < (plen << 3) + 15) {
590957b409SSimon J. Gerraty 		return 0;
600957b409SSimon J. Gerraty 	}
610957b409SSimon J. Gerraty 	br_i15_decode(t, pbuf, plen);
620957b409SSimon J. Gerraty 	p = t;
630957b409SSimon J. Gerraty 	plen = (p[0] + 31) >> 4;
640957b409SSimon J. Gerraty 	t += plen;
650957b409SSimon J. Gerraty 	tlen -= plen;
660957b409SSimon J. Gerraty 
670957b409SSimon J. Gerraty 	/*
680957b409SSimon J. Gerraty 	 * Decode q.
690957b409SSimon J. Gerraty 	 */
700957b409SSimon J. Gerraty 	if ((15 * tlen) < (qlen << 3) + 15) {
710957b409SSimon J. Gerraty 		return 0;
720957b409SSimon J. Gerraty 	}
730957b409SSimon J. Gerraty 	br_i15_decode(t, qbuf, qlen);
740957b409SSimon J. Gerraty 	q = t;
750957b409SSimon J. Gerraty 	qlen = (q[0] + 31) >> 4;
760957b409SSimon J. Gerraty 	t += qlen;
770957b409SSimon J. Gerraty 	tlen -= qlen;
780957b409SSimon J. Gerraty 
790957b409SSimon J. Gerraty 	/*
800957b409SSimon J. Gerraty 	 * Computation can proceed only if we have enough room for the
810957b409SSimon J. Gerraty 	 * modulus.
820957b409SSimon J. Gerraty 	 */
830957b409SSimon J. Gerraty 	if (tlen < (plen + qlen + 1)) {
840957b409SSimon J. Gerraty 		return 0;
850957b409SSimon J. Gerraty 	}
860957b409SSimon J. Gerraty 
870957b409SSimon J. Gerraty 	/*
880957b409SSimon J. Gerraty 	 * Private key already contains the modulus bit length, from which
890957b409SSimon J. Gerraty 	 * we can infer the output length. Even if n is NULL, we still had
900957b409SSimon J. Gerraty 	 * to decode p and q to make sure that the product can be computed.
910957b409SSimon J. Gerraty 	 */
920957b409SSimon J. Gerraty 	nlen = (sk->n_bitlen + 7) >> 3;
930957b409SSimon J. Gerraty 	if (n != NULL) {
940957b409SSimon J. Gerraty 		br_i15_zero(t, p[0]);
950957b409SSimon J. Gerraty 		br_i15_mulacc(t, p, q);
960957b409SSimon J. Gerraty 		br_i15_encode(n, nlen, t);
970957b409SSimon J. Gerraty 	}
980957b409SSimon J. Gerraty 	return nlen;
990957b409SSimon J. Gerraty }
100