quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

rsa_alt_helpers.c (13626B)


      1 /*
      2  *  Helper functions for the RSA module
      3  *
      4  *  Copyright The Mbed TLS Contributors
      5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      6  *
      7  */
      8 
      9 #include "common.h"
     10 
     11 #if defined(MBEDTLS_RSA_C)
     12 
     13 #include "mbedtls/rsa.h"
     14 #include "mbedtls/bignum.h"
     15 #include "rsa_alt_helpers.h"
     16 
     17 /*
     18  * Compute RSA prime factors from public and private exponents
     19  *
     20  * Summary of algorithm:
     21  * Setting F := lcm(P-1,Q-1), the idea is as follows:
     22  *
     23  * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2)
     24  *     is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the
     25  *     square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four
     26  *     possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1)
     27  *     or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime
     28  *     factors of N.
     29  *
     30  * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same
     31  *     construction still applies since (-)^K is the identity on the set of
     32  *     roots of 1 in Z/NZ.
     33  *
     34  * The public and private key primitives (-)^E and (-)^D are mutually inverse
     35  * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e.
     36  * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L.
     37  * Splitting L = 2^t * K with K odd, we have
     38  *
     39  *   DE - 1 = FL = (F/2) * (2^(t+1)) * K,
     40  *
     41  * so (F / 2) * K is among the numbers
     42  *
     43  *   (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord
     44  *
     45  * where ord is the order of 2 in (DE - 1).
     46  * We can therefore iterate through these numbers apply the construction
     47  * of (a) and (b) above to attempt to factor N.
     48  *
     49  */
     50 int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N,
     51                               mbedtls_mpi const *E, mbedtls_mpi const *D,
     52                               mbedtls_mpi *P, mbedtls_mpi *Q)
     53 {
     54     int ret = 0;
     55 
     56     uint16_t attempt;  /* Number of current attempt  */
     57     uint16_t iter;     /* Number of squares computed in the current attempt */
     58 
     59     uint16_t order;    /* Order of 2 in DE - 1 */
     60 
     61     mbedtls_mpi T;  /* Holds largest odd divisor of DE - 1     */
     62     mbedtls_mpi K;  /* Temporary holding the current candidate */
     63 
     64     const unsigned char primes[] = { 2,
     65                                      3,    5,    7,   11,   13,   17,   19,   23,
     66                                      29,   31,   37,   41,   43,   47,   53,   59,
     67                                      61,   67,   71,   73,   79,   83,   89,   97,
     68                                      101,  103,  107,  109,  113,  127,  131,  137,
     69                                      139,  149,  151,  157,  163,  167,  173,  179,
     70                                      181,  191,  193,  197,  199,  211,  223,  227,
     71                                      229,  233,  239,  241,  251 };
     72 
     73     const size_t num_primes = sizeof(primes) / sizeof(*primes);
     74 
     75     if (P == NULL || Q == NULL || P->p != NULL || Q->p != NULL) {
     76         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     77     }
     78 
     79     if (mbedtls_mpi_cmp_int(N, 0) <= 0 ||
     80         mbedtls_mpi_cmp_int(D, 1) <= 0 ||
     81         mbedtls_mpi_cmp_mpi(D, N) >= 0 ||
     82         mbedtls_mpi_cmp_int(E, 1) <= 0 ||
     83         mbedtls_mpi_cmp_mpi(E, N) >= 0) {
     84         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     85     }
     86 
     87     /*
     88      * Initializations and temporary changes
     89      */
     90 
     91     mbedtls_mpi_init(&K);
     92     mbedtls_mpi_init(&T);
     93 
     94     /* T := DE - 1 */
     95     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, D,  E));
     96     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&T, &T, 1));
     97 
     98     if ((order = (uint16_t) mbedtls_mpi_lsb(&T)) == 0) {
     99         ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    100         goto cleanup;
    101     }
    102 
    103     /* After this operation, T holds the largest odd divisor of DE - 1. */
    104     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&T, order));
    105 
    106     /*
    107      * Actual work
    108      */
    109 
    110     /* Skip trying 2 if N == 1 mod 8 */
    111     attempt = 0;
    112     if (N->p[0] % 8 == 1) {
    113         attempt = 1;
    114     }
    115 
    116     for (; attempt < num_primes; ++attempt) {
    117         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&K, primes[attempt]));
    118 
    119         /* Check if gcd(K,N) = 1 */
    120         MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(P, &K, N));
    121         if (mbedtls_mpi_cmp_int(P, 1) != 0) {
    122             continue;
    123         }
    124 
    125         /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ...
    126          * and check whether they have nontrivial GCD with N. */
    127         MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &K, &T, N,
    128                                             Q /* temporarily use Q for storing Montgomery
    129                                                * multiplication helper values */));
    130 
    131         for (iter = 1; iter <= order; ++iter) {
    132             /* If we reach 1 prematurely, there's no point
    133              * in continuing to square K */
    134             if (mbedtls_mpi_cmp_int(&K, 1) == 0) {
    135                 break;
    136             }
    137 
    138             MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&K, &K, 1));
    139             MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(P, &K, N));
    140 
    141             if (mbedtls_mpi_cmp_int(P, 1) ==  1 &&
    142                 mbedtls_mpi_cmp_mpi(P, N) == -1) {
    143                 /*
    144                  * Have found a nontrivial divisor P of N.
    145                  * Set Q := N / P.
    146                  */
    147 
    148                 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(Q, NULL, N, P));
    149                 goto cleanup;
    150             }
    151 
    152             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
    153             MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &K));
    154             MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, N));
    155         }
    156 
    157         /*
    158          * If we get here, then either we prematurely aborted the loop because
    159          * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must
    160          * be 1 if D,E,N were consistent.
    161          * Check if that's the case and abort if not, to avoid very long,
    162          * yet eventually failing, computations if N,D,E were not sane.
    163          */
    164         if (mbedtls_mpi_cmp_int(&K, 1) != 0) {
    165             break;
    166         }
    167     }
    168 
    169     ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    170 
    171 cleanup:
    172 
    173     mbedtls_mpi_free(&K);
    174     mbedtls_mpi_free(&T);
    175     return ret;
    176 }
    177 
    178 /*
    179  * Given P, Q and the public exponent E, deduce D.
    180  * This is essentially a modular inversion.
    181  */
    182 int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P,
    183                                         mbedtls_mpi const *Q,
    184                                         mbedtls_mpi const *E,
    185                                         mbedtls_mpi *D)
    186 {
    187     int ret = 0;
    188     mbedtls_mpi K, L;
    189 
    190     if (D == NULL || mbedtls_mpi_cmp_int(D, 0) != 0) {
    191         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    192     }
    193 
    194     if (mbedtls_mpi_cmp_int(P, 1) <= 0 ||
    195         mbedtls_mpi_cmp_int(Q, 1) <= 0 ||
    196         mbedtls_mpi_cmp_int(E, 0) == 0) {
    197         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    198     }
    199 
    200     mbedtls_mpi_init(&K);
    201     mbedtls_mpi_init(&L);
    202 
    203     /* Temporarily put K := P-1 and L := Q-1 */
    204     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
    205     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1));
    206 
    207     /* Temporarily put D := gcd(P-1, Q-1) */
    208     MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(D, &K, &L));
    209 
    210     /* K := LCM(P-1, Q-1) */
    211     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &L));
    212     MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&K, NULL, &K, D));
    213 
    214     /* Compute modular inverse of E in LCM(P-1, Q-1) */
    215     MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(D, E, &K));
    216 
    217 cleanup:
    218 
    219     mbedtls_mpi_free(&K);
    220     mbedtls_mpi_free(&L);
    221 
    222     return ret;
    223 }
    224 
    225 int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
    226                            const mbedtls_mpi *D, mbedtls_mpi *DP,
    227                            mbedtls_mpi *DQ, mbedtls_mpi *QP)
    228 {
    229     int ret = 0;
    230     mbedtls_mpi K;
    231     mbedtls_mpi_init(&K);
    232 
    233     /* DP = D mod P-1 */
    234     if (DP != NULL) {
    235         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
    236         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DP, D, &K));
    237     }
    238 
    239     /* DQ = D mod Q-1 */
    240     if (DQ != NULL) {
    241         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1));
    242         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DQ, D, &K));
    243     }
    244 
    245     /* QP = Q^{-1} mod P */
    246     if (QP != NULL) {
    247         MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(QP, Q, P));
    248     }
    249 
    250 cleanup:
    251     mbedtls_mpi_free(&K);
    252 
    253     return ret;
    254 }
    255 
    256 /*
    257  * Check that core RSA parameters are sane.
    258  */
    259 int mbedtls_rsa_validate_params(const mbedtls_mpi *N, const mbedtls_mpi *P,
    260                                 const mbedtls_mpi *Q, const mbedtls_mpi *D,
    261                                 const mbedtls_mpi *E,
    262                                 int (*f_rng)(void *, unsigned char *, size_t),
    263                                 void *p_rng)
    264 {
    265     int ret = 0;
    266     mbedtls_mpi K, L;
    267 
    268     mbedtls_mpi_init(&K);
    269     mbedtls_mpi_init(&L);
    270 
    271     /*
    272      * Step 1: If PRNG provided, check that P and Q are prime
    273      */
    274 
    275 #if defined(MBEDTLS_GENPRIME)
    276     /*
    277      * When generating keys, the strongest security we support aims for an error
    278      * rate of at most 2^-100 and we are aiming for the same certainty here as
    279      * well.
    280      */
    281     if (f_rng != NULL && P != NULL &&
    282         (ret = mbedtls_mpi_is_prime_ext(P, 50, f_rng, p_rng)) != 0) {
    283         ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    284         goto cleanup;
    285     }
    286 
    287     if (f_rng != NULL && Q != NULL &&
    288         (ret = mbedtls_mpi_is_prime_ext(Q, 50, f_rng, p_rng)) != 0) {
    289         ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    290         goto cleanup;
    291     }
    292 #else
    293     ((void) f_rng);
    294     ((void) p_rng);
    295 #endif /* MBEDTLS_GENPRIME */
    296 
    297     /*
    298      * Step 2: Check that 1 < N = P * Q
    299      */
    300 
    301     if (P != NULL && Q != NULL && N != NULL) {
    302         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, P, Q));
    303         if (mbedtls_mpi_cmp_int(N, 1)  <= 0 ||
    304             mbedtls_mpi_cmp_mpi(&K, N) != 0) {
    305             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    306             goto cleanup;
    307         }
    308     }
    309 
    310     /*
    311      * Step 3: Check and 1 < D, E < N if present.
    312      */
    313 
    314     if (N != NULL && D != NULL && E != NULL) {
    315         if (mbedtls_mpi_cmp_int(D, 1) <= 0 ||
    316             mbedtls_mpi_cmp_int(E, 1) <= 0 ||
    317             mbedtls_mpi_cmp_mpi(D, N) >= 0 ||
    318             mbedtls_mpi_cmp_mpi(E, N) >= 0) {
    319             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    320             goto cleanup;
    321         }
    322     }
    323 
    324     /*
    325      * Step 4: Check that D, E are inverse modulo P-1 and Q-1
    326      */
    327 
    328     if (P != NULL && Q != NULL && D != NULL && E != NULL) {
    329         if (mbedtls_mpi_cmp_int(P, 1) <= 0 ||
    330             mbedtls_mpi_cmp_int(Q, 1) <= 0) {
    331             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    332             goto cleanup;
    333         }
    334 
    335         /* Compute DE-1 mod P-1 */
    336         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E));
    337         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
    338         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, P, 1));
    339         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L));
    340         if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
    341             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    342             goto cleanup;
    343         }
    344 
    345         /* Compute DE-1 mod Q-1 */
    346         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E));
    347         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
    348         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1));
    349         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L));
    350         if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
    351             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    352             goto cleanup;
    353         }
    354     }
    355 
    356 cleanup:
    357 
    358     mbedtls_mpi_free(&K);
    359     mbedtls_mpi_free(&L);
    360 
    361     /* Wrap MPI error codes by RSA check failure error code */
    362     if (ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) {
    363         ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    364     }
    365 
    366     return ret;
    367 }
    368 
    369 /*
    370  * Check that RSA CRT parameters are in accordance with core parameters.
    371  */
    372 int mbedtls_rsa_validate_crt(const mbedtls_mpi *P,  const mbedtls_mpi *Q,
    373                              const mbedtls_mpi *D,  const mbedtls_mpi *DP,
    374                              const mbedtls_mpi *DQ, const mbedtls_mpi *QP)
    375 {
    376     int ret = 0;
    377 
    378     mbedtls_mpi K, L;
    379     mbedtls_mpi_init(&K);
    380     mbedtls_mpi_init(&L);
    381 
    382     /* Check that DP - D == 0 mod P - 1 */
    383     if (DP != NULL) {
    384         if (P == NULL) {
    385             ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
    386             goto cleanup;
    387         }
    388 
    389         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
    390         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DP, D));
    391         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K));
    392 
    393         if (mbedtls_mpi_cmp_int(&L, 0) != 0) {
    394             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    395             goto cleanup;
    396         }
    397     }
    398 
    399     /* Check that DQ - D == 0 mod Q - 1 */
    400     if (DQ != NULL) {
    401         if (Q == NULL) {
    402             ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
    403             goto cleanup;
    404         }
    405 
    406         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1));
    407         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DQ, D));
    408         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K));
    409 
    410         if (mbedtls_mpi_cmp_int(&L, 0) != 0) {
    411             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    412             goto cleanup;
    413         }
    414     }
    415 
    416     /* Check that QP * Q - 1 == 0 mod P */
    417     if (QP != NULL) {
    418         if (P == NULL || Q == NULL) {
    419             ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
    420             goto cleanup;
    421         }
    422 
    423         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, QP, Q));
    424         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
    425         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, P));
    426         if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
    427             ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    428             goto cleanup;
    429         }
    430     }
    431 
    432 cleanup:
    433 
    434     /* Wrap MPI error codes by RSA check failure error code */
    435     if (ret != 0 &&
    436         ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED &&
    437         ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA) {
    438         ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
    439     }
    440 
    441     mbedtls_mpi_free(&K);
    442     mbedtls_mpi_free(&L);
    443 
    444     return ret;
    445 }
    446 
    447 #endif /* MBEDTLS_RSA_C */