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