Skip to main content
  • Home
  • login
  • Browse the archive

    swh mirror partner logo
swh logo
SoftwareHeritage
Software
Heritage
Mirror
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

swh:1:snp:dc2a5002442a00b1c0eda7c65d04ea7455e166cd
  • Code
  • Branches (204)
  • Releases (207)
    • Branches
    • Releases
    • HEAD
    • refs/heads/OpenSSL-engine-0_9_6-stable
    • refs/heads/OpenSSL-fips-0_9_7-stable
    • refs/heads/OpenSSL-fips-0_9_8-stable
    • refs/heads/OpenSSL-fips-1_2-stable
    • refs/heads/OpenSSL-fips-2_0-dev
    • refs/heads/OpenSSL-fips-2_0-stable
    • refs/heads/OpenSSL-fips2-0_9_7-stable
    • refs/heads/OpenSSL_0_9_6-stable
    • refs/heads/OpenSSL_0_9_7-stable
    • refs/heads/OpenSSL_0_9_8-stable
    • refs/heads/OpenSSL_0_9_8fg-stable
    • refs/heads/OpenSSL_1_0_0-stable
    • refs/heads/OpenSSL_1_0_1-stable
    • refs/heads/OpenSSL_1_0_2-stable
    • refs/heads/OpenSSL_1_1_0-stable
    • refs/heads/OpenSSL_1_1_1-stable
    • refs/heads/SSLeay
    • refs/heads/feature/dtls-1.3
    • refs/heads/feature/ech
    • refs/heads/feature/quic-server
    • refs/heads/master
    • refs/heads/openssl-3.0
    • refs/heads/openssl-3.1
    • refs/heads/openssl-3.2
    • refs/heads/openssl-3.3
    • refs/heads/openssl-3.4
    • refs/heads/tls1.3-draft-18
    • refs/heads/tls1.3-draft-19
    • refs/tags/AFTER_COMPAQ_PATCH
    • refs/tags/BEFORE_COMPAQ_PATCH
    • refs/tags/BEFORE_engine
    • refs/tags/BEN_FIPS_TEST_1
    • refs/tags/BEN_FIPS_TEST_2
    • refs/tags/BEN_FIPS_TEST_3
    • refs/tags/BEN_FIPS_TEST_4
    • refs/tags/BEN_FIPS_TEST_5
    • refs/tags/BEN_FIPS_TEST_6
    • refs/tags/BEN_FIPS_TEST_7
    • refs/tags/BEN_FIPS_TEST_8
    • refs/tags/FIPS_098_TEST_1
    • refs/tags/FIPS_098_TEST_2
    • refs/tags/FIPS_098_TEST_3
    • refs/tags/FIPS_098_TEST_4
    • refs/tags/FIPS_098_TEST_5
    • refs/tags/FIPS_098_TEST_6
    • refs/tags/FIPS_098_TEST_7
    • refs/tags/FIPS_098_TEST_8
    • refs/tags/FIPS_TEST_10
    • refs/tags/FIPS_TEST_9
    • refs/tags/LEVITTE_after_const
    • refs/tags/LEVITTE_before_const
    • refs/tags/OpenSSL-engine-0_9_6
    • refs/tags/OpenSSL-engine-0_9_6-beta1
    • refs/tags/OpenSSL-engine-0_9_6-beta2
    • refs/tags/OpenSSL-engine-0_9_6-beta3
    • refs/tags/OpenSSL-engine-0_9_6a
    • refs/tags/OpenSSL-engine-0_9_6a-beta1
    • refs/tags/OpenSSL-engine-0_9_6a-beta2
    • refs/tags/OpenSSL-engine-0_9_6a-beta3
    • refs/tags/OpenSSL-engine-0_9_6b
    • refs/tags/OpenSSL-engine-0_9_6c
    • refs/tags/OpenSSL-engine-0_9_6d
    • refs/tags/OpenSSL-engine-0_9_6d-beta1
    • refs/tags/OpenSSL-engine-0_9_6e
    • refs/tags/OpenSSL-engine-0_9_6f
    • refs/tags/OpenSSL-engine-0_9_6g
    • refs/tags/OpenSSL-engine-0_9_6h
    • refs/tags/OpenSSL-engine-0_9_6i
    • refs/tags/OpenSSL-engine-0_9_6j
    • refs/tags/OpenSSL-engine-0_9_6k
    • refs/tags/OpenSSL-engine-0_9_6l
    • refs/tags/OpenSSL-engine-0_9_6m
    • refs/tags/OpenSSL-fips-1_2_0
    • refs/tags/OpenSSL-fips-1_2_1
    • refs/tags/OpenSSL-fips-1_2_2
    • refs/tags/OpenSSL-fips-1_2_3
    • refs/tags/OpenSSL-fips-2_0
    • refs/tags/OpenSSL-fips-2_0-pl1
    • refs/tags/OpenSSL-fips-2_0-rc1
    • refs/tags/OpenSSL-fips-2_0-rc2
    • refs/tags/OpenSSL-fips-2_0-rc3
    • refs/tags/OpenSSL-fips-2_0-rc4
    • refs/tags/OpenSSL-fips-2_0-rc5
    • refs/tags/OpenSSL-fips-2_0-rc6
    • refs/tags/OpenSSL-fips-2_0-rc7
    • refs/tags/OpenSSL-fips-2_0-rc8
    • refs/tags/OpenSSL-fips-2_0-rc9
    • refs/tags/OpenSSL-fips-2_0_1
    • refs/tags/OpenSSL_0_9_1c
    • refs/tags/OpenSSL_0_9_2b
    • refs/tags/OpenSSL_0_9_3
    • refs/tags/OpenSSL_0_9_3a
    • refs/tags/OpenSSL_0_9_3beta1
    • refs/tags/OpenSSL_0_9_3beta2
    • refs/tags/OpenSSL_0_9_4
    • refs/tags/OpenSSL_0_9_5
    • refs/tags/OpenSSL_0_9_5a
    • refs/tags/OpenSSL_0_9_5a-beta1
    • refs/tags/OpenSSL_0_9_5a-beta2
    • refs/tags/OpenSSL_0_9_5beta1
    • refs/tags/OpenSSL_0_9_5beta2
    • refs/tags/OpenSSL_0_9_6
    • refs/tags/OpenSSL_0_9_6-beta1
    • refs/tags/OpenSSL_0_9_6-beta2
    • refs/tags/OpenSSL_0_9_6-beta3
    • refs/tags/OpenSSL_0_9_6a
    • refs/tags/OpenSSL_0_9_6a-beta1
    • refs/tags/OpenSSL_0_9_6a-beta2
    • refs/tags/OpenSSL_0_9_6a-beta3
    • refs/tags/OpenSSL_0_9_6b
    • refs/tags/OpenSSL_0_9_6c
    • refs/tags/OpenSSL_0_9_6d
    • refs/tags/OpenSSL_0_9_6d-beta1
    • refs/tags/OpenSSL_0_9_6e
    • refs/tags/OpenSSL_0_9_6f
    • refs/tags/OpenSSL_0_9_6g
    • refs/tags/OpenSSL_0_9_6h
    • refs/tags/OpenSSL_0_9_6i
    • refs/tags/OpenSSL_0_9_6j
    • refs/tags/OpenSSL_0_9_6k
    • refs/tags/OpenSSL_0_9_6l
    • refs/tags/OpenSSL_0_9_6m
    • refs/tags/OpenSSL_0_9_7
    • refs/tags/OpenSSL_0_9_7-beta1
    • refs/tags/OpenSSL_0_9_7-beta2
    • refs/tags/OpenSSL_0_9_7-beta3
    • refs/tags/OpenSSL_0_9_7-beta4
    • refs/tags/OpenSSL_0_9_7-beta5
    • refs/tags/OpenSSL_0_9_7-beta6
    • refs/tags/OpenSSL_0_9_7a
    • refs/tags/OpenSSL_0_9_7b
    • refs/tags/OpenSSL_0_9_7c
    • refs/tags/OpenSSL_0_9_7d
    • refs/tags/OpenSSL_0_9_7e
    • refs/tags/OpenSSL_0_9_7f
    • refs/tags/OpenSSL_0_9_7g
    • refs/tags/OpenSSL_0_9_7h
    • refs/tags/OpenSSL_0_9_7i
    • refs/tags/OpenSSL_0_9_7j
    • refs/tags/OpenSSL_0_9_7k
    • refs/tags/OpenSSL_0_9_7l
    • refs/tags/OpenSSL_0_9_7m
    • refs/tags/OpenSSL_0_9_8
    • refs/tags/OpenSSL_0_9_8-beta1
    • refs/tags/OpenSSL_0_9_8-beta2
    • refs/tags/OpenSSL_0_9_8-beta3
    • refs/tags/OpenSSL_0_9_8-beta4
    • refs/tags/OpenSSL_0_9_8-beta5
    • refs/tags/OpenSSL_0_9_8-beta6
    • refs/tags/OpenSSL_0_9_8a
    • refs/tags/OpenSSL_0_9_8b
    • refs/tags/OpenSSL_0_9_8c
    • refs/tags/OpenSSL_0_9_8d
    • refs/tags/OpenSSL_0_9_8e
    • refs/tags/OpenSSL_0_9_8f
    • refs/tags/OpenSSL_0_9_8g
    • refs/tags/OpenSSL_0_9_8h
    • refs/tags/OpenSSL_0_9_8i
    • refs/tags/OpenSSL_0_9_8j
    • refs/tags/OpenSSL_0_9_8k
    • refs/tags/OpenSSL_0_9_8l
    • refs/tags/OpenSSL_0_9_8m
    • refs/tags/OpenSSL_0_9_8m-beta1
    • refs/tags/OpenSSL_0_9_8n
    • refs/tags/OpenSSL_0_9_8o
    • refs/tags/OpenSSL_0_9_8p
    • refs/tags/OpenSSL_0_9_8q
    • refs/tags/OpenSSL_0_9_8r
    • refs/tags/OpenSSL_0_9_8s
    • refs/tags/OpenSSL_0_9_8t
    • refs/tags/OpenSSL_0_9_8u
    • refs/tags/OpenSSL_0_9_8v
    • refs/tags/OpenSSL_0_9_8w
    • refs/tags/OpenSSL_0_9_8x
    • refs/tags/OpenSSL_1_0_0
    • refs/tags/OpenSSL_1_0_0-beta1
    • refs/tags/OpenSSL_1_0_0-beta2
    • refs/tags/OpenSSL_1_0_0-beta3
    • refs/tags/OpenSSL_1_0_0-beta4
    • refs/tags/OpenSSL_1_0_0-beta5
    • refs/tags/OpenSSL_1_0_0a
    • refs/tags/OpenSSL_1_0_0b
    • refs/tags/OpenSSL_1_0_0c
    • refs/tags/OpenSSL_1_0_0d
    • refs/tags/OpenSSL_1_0_0e
    • refs/tags/OpenSSL_1_0_0f
    • refs/tags/OpenSSL_1_0_0g
    • refs/tags/OpenSSL_1_0_0h
    • refs/tags/OpenSSL_1_0_0i
    • refs/tags/OpenSSL_1_0_0j
    • refs/tags/OpenSSL_1_0_1
    • refs/tags/OpenSSL_1_0_1-beta1
    • refs/tags/OpenSSL_1_0_1-beta2
    • refs/tags/OpenSSL_1_0_1-beta3
    • refs/tags/OpenSSL_1_0_1a
    • refs/tags/OpenSSL_1_0_1b
    • refs/tags/OpenSSL_1_0_1c
    • refs/tags/OpenSSL_FIPS_1_0
    • refs/tags/SSLeay_0_8_1b
    • refs/tags/SSLeay_0_9_0b
    • refs/tags/SSLeay_0_9_1b
    • refs/tags/STATE_after_zlib
    • refs/tags/STATE_before_zlib
    • refs/tags/rsaref
    • openssl-3.4.0-alpha1
    • openssl-3.3.2
    • openssl-3.3.1
    • openssl-3.3.0-beta1
    • openssl-3.3.0-alpha1
    • openssl-3.3.0
    • openssl-3.2.3
    • openssl-3.2.2
    • openssl-3.2.1
    • openssl-3.2.0-beta1
    • openssl-3.2.0-alpha2
    • openssl-3.2.0-alpha1
    • openssl-3.2.0
    • openssl-3.1.7
    • openssl-3.1.6
    • openssl-3.1.5
    • openssl-3.1.4
    • openssl-3.1.3
    • openssl-3.1.2
    • openssl-3.1.1
    • openssl-3.1.0-beta1
    • openssl-3.1.0-alpha1
    • openssl-3.1.0
    • openssl-3.0.9
    • openssl-3.0.8
    • openssl-3.0.7
    • openssl-3.0.6
    • openssl-3.0.5
    • openssl-3.0.4
    • openssl-3.0.3
    • openssl-3.0.2
    • openssl-3.0.15
    • openssl-3.0.14
    • openssl-3.0.13
    • openssl-3.0.12
    • openssl-3.0.11
    • openssl-3.0.10
    • openssl-3.0.1
    • openssl-3.0.0-beta2
    • openssl-3.0.0-beta1
    • openssl-3.0.0-alpha9
    • openssl-3.0.0-alpha8
    • openssl-3.0.0-alpha7
    • openssl-3.0.0-alpha6
    • openssl-3.0.0-alpha5
    • openssl-3.0.0-alpha4
    • openssl-3.0.0-alpha3
    • openssl-3.0.0-alpha2
    • openssl-3.0.0-alpha17
    • openssl-3.0.0-alpha16
    • openssl-3.0.0-alpha15
    • openssl-3.0.0-alpha14
    • openssl-3.0.0-alpha13
    • openssl-3.0.0-alpha12
    • openssl-3.0.0-alpha11
    • openssl-3.0.0-alpha10
    • openssl-3.0.0-alpha1
    • openssl-3.0.0
    • master-pre-reformat
    • master-pre-auto-reformat
    • master-post-reformat
    • master-post-auto-reformat
    • OpenSSL_1_1_1w
    • OpenSSL_1_1_1v
    • OpenSSL_1_1_1u
    • OpenSSL_1_1_1t
    • OpenSSL_1_1_1s
    • OpenSSL_1_1_1r
    • OpenSSL_1_1_1q
    • OpenSSL_1_1_1p
    • OpenSSL_1_1_1o
    • OpenSSL_1_1_1n
    • OpenSSL_1_1_1m
    • OpenSSL_1_1_1l
    • OpenSSL_1_1_1k
    • OpenSSL_1_1_1j
    • OpenSSL_1_1_1i
    • OpenSSL_1_1_1h
    • OpenSSL_1_1_1g
    • OpenSSL_1_1_1f
    • OpenSSL_1_1_1e
    • OpenSSL_1_1_1d
    • OpenSSL_1_1_1c
    • OpenSSL_1_1_1b
    • OpenSSL_1_1_1a
    • OpenSSL_1_1_1-pre9
    • OpenSSL_1_1_1-pre8
    • OpenSSL_1_1_1-pre7
    • OpenSSL_1_1_1-pre6
    • OpenSSL_1_1_1-pre5
    • OpenSSL_1_1_1-pre4
    • OpenSSL_1_1_1-pre3
    • OpenSSL_1_1_1-pre2
    • OpenSSL_1_1_1-pre1
    • OpenSSL_1_1_1
    • OpenSSL_1_1_0l
    • OpenSSL_1_1_0k
    • OpenSSL_1_1_0j
    • OpenSSL_1_1_0i
    • OpenSSL_1_1_0h
    • OpenSSL_1_1_0g
    • OpenSSL_1_1_0f
    • OpenSSL_1_1_0e
    • OpenSSL_1_1_0d
    • OpenSSL_1_1_0c
    • OpenSSL_1_1_0b
    • OpenSSL_1_1_0a
    • OpenSSL_1_1_0-pre6
    • OpenSSL_1_1_0-pre5
    • OpenSSL_1_1_0-pre4
    • OpenSSL_1_1_0-pre3
    • OpenSSL_1_1_0-pre2
    • OpenSSL_1_1_0-pre1
    • OpenSSL_1_1_0
    • OpenSSL_1_0_2u
    • OpenSSL_1_0_2t
    • OpenSSL_1_0_2s
    • OpenSSL_1_0_2r
    • OpenSSL_1_0_2q
    • OpenSSL_1_0_2p
    • OpenSSL_1_0_2o
    • OpenSSL_1_0_2n
    • OpenSSL_1_0_2m
    • OpenSSL_1_0_2l
    • OpenSSL_1_0_2k
    • OpenSSL_1_0_2j
    • OpenSSL_1_0_2i
    • OpenSSL_1_0_2h
    • OpenSSL_1_0_2g
    • OpenSSL_1_0_2f
    • OpenSSL_1_0_2e
    • OpenSSL_1_0_2d
    • OpenSSL_1_0_2c
    • OpenSSL_1_0_2b
    • OpenSSL_1_0_2a
    • OpenSSL_1_0_2-pre-reformat
    • OpenSSL_1_0_2-pre-auto-reformat
    • OpenSSL_1_0_2-post-reformat
    • OpenSSL_1_0_2-post-auto-reformat
    • OpenSSL_1_0_2-beta3
    • OpenSSL_1_0_2-beta2
    • OpenSSL_1_0_2-beta1
    • OpenSSL_1_0_2
    • OpenSSL_1_0_1u
    • OpenSSL_1_0_1t
    • OpenSSL_1_0_1s
    • OpenSSL_1_0_1r
    • OpenSSL_1_0_1q
    • OpenSSL_1_0_1p
    • OpenSSL_1_0_1o
    • OpenSSL_1_0_1n
    • OpenSSL_1_0_1m
    • OpenSSL_1_0_1l
    • OpenSSL_1_0_1k
    • OpenSSL_1_0_1j
    • OpenSSL_1_0_1i
    • OpenSSL_1_0_1h
    • OpenSSL_1_0_1g
    • OpenSSL_1_0_1f
    • OpenSSL_1_0_1e
    • OpenSSL_1_0_1d
    • OpenSSL_1_0_1-pre-reformat
    • OpenSSL_1_0_1-pre-auto-reformat
    • OpenSSL_1_0_1-post-reformat
    • OpenSSL_1_0_1-post-auto-reformat
    • OpenSSL_1_0_0t
    • OpenSSL_1_0_0s
    • OpenSSL_1_0_0r
    • OpenSSL_1_0_0q
    • OpenSSL_1_0_0p
    • OpenSSL_1_0_0o
    • OpenSSL_1_0_0n
    • OpenSSL_1_0_0m
    • OpenSSL_1_0_0l
    • OpenSSL_1_0_0k
    • OpenSSL_1_0_0-pre-reformat
    • OpenSSL_1_0_0-pre-auto-reformat
    • OpenSSL_1_0_0-post-reformat
    • OpenSSL_1_0_0-post-auto-reformat
    • OpenSSL_0_9_8zh
    • OpenSSL_0_9_8zg
    • OpenSSL_0_9_8zf
    • OpenSSL_0_9_8ze
    • OpenSSL_0_9_8zd
    • OpenSSL_0_9_8zc
    • OpenSSL_0_9_8zb
    • OpenSSL_0_9_8za
    • OpenSSL_0_9_8y
    • OpenSSL_0_9_8-pre-reformat
    • OpenSSL_0_9_8-pre-auto-reformat
    • OpenSSL_0_9_8-post-reformat
    • OpenSSL_0_9_8-post-auto-reformat
    • OpenSSL-fips-2_0_9
    • OpenSSL-fips-2_0_8
    • OpenSSL-fips-2_0_7
    • OpenSSL-fips-2_0_6
    • OpenSSL-fips-2_0_5
    • OpenSSL-fips-2_0_4
    • OpenSSL-fips-2_0_3
    • OpenSSL-fips-2_0_2
    • OpenSSL-fips-2_0_16
    • OpenSSL-fips-2_0_15
    • OpenSSL-fips-2_0_14
    • OpenSSL-fips-2_0_13
    • OpenSSL-fips-2_0_12
    • OpenSSL-fips-2_0_11
    • OpenSSL-fips-2_0_10
  • e7e7350
  • /
  • crypto
  • /
  • rsa
  • /
  • rsa_gen.c
Raw File
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
  • revision
  • snapshot
  • release
content badge Iframe embedding
swh:1:cnt:29056a62a1ae0145df81ae225c5e191eeaf862c2
directory badge Iframe embedding
swh:1:dir:8785b124450cc2bdee35cc05ec5dbf29ada095aa
revision badge
swh:1:rev:9398e4038c27d5ef15111c61e984d4d2be8a52a8
snapshot badge
swh:1:snp:dc2a5002442a00b1c0eda7c65d04ea7455e166cd
release badge
swh:1:rel:ca44a6f8fdfe8141e6d0bf2d744471cd48ba9851
Tip revision: 9398e4038c27d5ef15111c61e984d4d2be8a52a8 authored by Matt Caswell on 01 August 2023, 13:51:35 UTC
Prepare for release of 1.1.1v
Tip revision: 9398e40
rsa_gen.c
/*
 * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * NB: these functions have been "upgraded", the deprecated versions (which
 * are compatibility wrappers using these functions) are in rsa_depr.c. -
 * Geoff
 */

#include <stdio.h>
#include <time.h>
#include "internal/cryptlib.h"
#include <openssl/bn.h>
#include "rsa_local.h"

static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
                              BN_GENCB *cb);

/*
 * NB: this wrapper would normally be placed in rsa_lib.c and the static
 * implementation would probably be in rsa_eay.c. Nonetheless, is kept here
 * so that we don't introduce a new linker dependency. Eg. any application
 * that wasn't previously linking object code related to key-generation won't
 * have to now just because key-generation is part of RSA_METHOD.
 */
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
{
    if (rsa->meth->rsa_keygen != NULL)
        return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);

    return RSA_generate_multi_prime_key(rsa, bits, RSA_DEFAULT_PRIME_NUM,
                                        e_value, cb);
}

int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes,
                                 BIGNUM *e_value, BN_GENCB *cb)
{
    /* multi-prime is only supported with the builtin key generation */
    if (rsa->meth->rsa_multi_prime_keygen != NULL) {
        return rsa->meth->rsa_multi_prime_keygen(rsa, bits, primes,
                                                 e_value, cb);
    } else if (rsa->meth->rsa_keygen != NULL) {
        /*
         * However, if rsa->meth implements only rsa_keygen, then we
         * have to honour it in 2-prime case and assume that it wouldn't
         * know what to do with multi-prime key generated by builtin
         * subroutine...
         */
        if (primes == 2)
            return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
        else
            return 0;
    }

    return rsa_builtin_keygen(rsa, bits, primes, e_value, cb);
}

static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
                              BN_GENCB *cb)
{
    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime;
    int ok = -1, n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
    int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0;
    RSA_PRIME_INFO *pinfo = NULL;
    STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL;
    BN_CTX *ctx = NULL;
    BN_ULONG bitst = 0;
    unsigned long error = 0;

    if (bits < RSA_MIN_MODULUS_BITS) {
        ok = 0;             /* we set our own err */
        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
        goto err;
    }

    if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) {
        ok = 0;             /* we set our own err */
        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_PRIME_NUM_INVALID);
        goto err;
    }

    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;
    BN_CTX_start(ctx);
    r0 = BN_CTX_get(ctx);
    r1 = BN_CTX_get(ctx);
    r2 = BN_CTX_get(ctx);
    if (r2 == NULL)
        goto err;

    /* divide bits into 'primes' pieces evenly */
    quo = bits / primes;
    rmd = bits % primes;

    for (i = 0; i < primes; i++)
        bitsr[i] = (i < rmd) ? quo + 1 : quo;

    /* We need the RSA components non-NULL */
    if (!rsa->n && ((rsa->n = BN_new()) == NULL))
        goto err;
    if (!rsa->d && ((rsa->d = BN_secure_new()) == NULL))
        goto err;
    if (!rsa->e && ((rsa->e = BN_new()) == NULL))
        goto err;
    if (!rsa->p && ((rsa->p = BN_secure_new()) == NULL))
        goto err;
    if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL))
        goto err;
    if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL))
        goto err;
    if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL))
        goto err;
    if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL))
        goto err;

    /* initialize multi-prime components */
    if (primes > RSA_DEFAULT_PRIME_NUM) {
        rsa->version = RSA_ASN1_VERSION_MULTI;
        prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, primes - 2);
        if (prime_infos == NULL)
            goto err;
        if (rsa->prime_infos != NULL) {
            /* could this happen? */
            sk_RSA_PRIME_INFO_pop_free(rsa->prime_infos, rsa_multip_info_free);
        }
        rsa->prime_infos = prime_infos;

        /* prime_info from 2 to |primes| -1 */
        for (i = 2; i < primes; i++) {
            pinfo = rsa_multip_info_new();
            if (pinfo == NULL)
                goto err;
            (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo);
        }
    }

    if (BN_copy(rsa->e, e_value) == NULL)
        goto err;

    /* generate p, q and other primes (if any) */
    for (i = 0; i < primes; i++) {
        adj = 0;
        retries = 0;

        if (i == 0) {
            prime = rsa->p;
        } else if (i == 1) {
            prime = rsa->q;
        } else {
            pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2);
            prime = pinfo->r;
        }
        BN_set_flags(prime, BN_FLG_CONSTTIME);

        for (;;) {
 redo:
            if (!BN_generate_prime_ex(prime, bitsr[i] + adj, 0, NULL, NULL, cb))
                goto err;
            /*
             * prime should not be equal to p, q, r_3...
             * (those primes prior to this one)
             */
            {
                int j;

                for (j = 0; j < i; j++) {
                    BIGNUM *prev_prime;

                    if (j == 0)
                        prev_prime = rsa->p;
                    else if (j == 1)
                        prev_prime = rsa->q;
                    else
                        prev_prime = sk_RSA_PRIME_INFO_value(prime_infos,
                                                             j - 2)->r;

                    if (!BN_cmp(prime, prev_prime)) {
                        goto redo;
                    }
                }
            }
            if (!BN_sub(r2, prime, BN_value_one()))
                goto err;
            ERR_set_mark();
            BN_set_flags(r2, BN_FLG_CONSTTIME);
            if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
               /* GCD == 1 since inverse exists */
                break;
            }
            error = ERR_peek_last_error();
            if (ERR_GET_LIB(error) == ERR_LIB_BN
                && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
                /* GCD != 1 */
                ERR_pop_to_mark();
            } else {
                goto err;
            }
            if (!BN_GENCB_call(cb, 2, n++))
                goto err;
        }

        bitse += bitsr[i];

        /* calculate n immediately to see if it's sufficient */
        if (i == 1) {
            /* we get at least 2 primes */
            if (!BN_mul(r1, rsa->p, rsa->q, ctx))
                goto err;
        } else if (i != 0) {
            /* modulus n = p * q * r_3 * r_4 ... */
            if (!BN_mul(r1, rsa->n, prime, ctx))
                goto err;
        } else {
            /* i == 0, do nothing */
            if (!BN_GENCB_call(cb, 3, i))
                goto err;
            continue;
        }
        /*
         * if |r1|, product of factors so far, is not as long as expected
         * (by checking the first 4 bits are less than 0x9 or greater than
         * 0xF). If so, re-generate the last prime.
         *
         * NOTE: This actually can't happen in two-prime case, because of
         * the way factors are generated.
         *
         * Besides, another consideration is, for multi-prime case, even the
         * length modulus is as long as expected, the modulus could start at
         * 0x8, which could be utilized to distinguish a multi-prime private
         * key by using the modulus in a certificate. This is also covered
         * by checking the length should not be less than 0x9.
         */
        if (!BN_rshift(r2, r1, bitse - 4))
            goto err;
        bitst = BN_get_word(r2);

        if (bitst < 0x9 || bitst > 0xF) {
            /*
             * For keys with more than 4 primes, we attempt longer factor to
             * meet length requirement.
             *
             * Otherwise, we just re-generate the prime with the same length.
             *
             * This strategy has the following goals:
             *
             * 1. 1024-bit factors are efficient when using 3072 and 4096-bit key
             * 2. stay the same logic with normal 2-prime key
             */
            bitse -= bitsr[i];
            if (!BN_GENCB_call(cb, 2, n++))
                goto err;
            if (primes > 4) {
                if (bitst < 0x9)
                    adj++;
                else
                    adj--;
            } else if (retries == 4) {
                /*
                 * re-generate all primes from scratch, mainly used
                 * in 4 prime case to avoid long loop. Max retry times
                 * is set to 4.
                 */
                i = -1;
                bitse = 0;
                continue;
            }
            retries++;
            goto redo;
        }
        /* save product of primes for further use, for multi-prime only */
        if (i > 1 && BN_copy(pinfo->pp, rsa->n) == NULL)
            goto err;
        if (BN_copy(rsa->n, r1) == NULL)
            goto err;
        if (!BN_GENCB_call(cb, 3, i))
            goto err;
    }

    if (BN_cmp(rsa->p, rsa->q) < 0) {
        tmp = rsa->p;
        rsa->p = rsa->q;
        rsa->q = tmp;
    }

    /* calculate d */

    /* p - 1 */
    if (!BN_sub(r1, rsa->p, BN_value_one()))
        goto err;
    /* q - 1 */
    if (!BN_sub(r2, rsa->q, BN_value_one()))
        goto err;
    /* (p - 1)(q - 1) */
    if (!BN_mul(r0, r1, r2, ctx))
        goto err;
    /* multi-prime */
    for (i = 2; i < primes; i++) {
        pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2);
        /* save r_i - 1 to pinfo->d temporarily */
        if (!BN_sub(pinfo->d, pinfo->r, BN_value_one()))
            goto err;
        if (!BN_mul(r0, r0, pinfo->d, ctx))
            goto err;
    }

    {
        BIGNUM *pr0 = BN_new();

        if (pr0 == NULL)
            goto err;

        BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
        if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
            BN_free(pr0);
            goto err;               /* d */
        }
        /* We MUST free pr0 before any further use of r0 */
        BN_free(pr0);
    }

    {
        BIGNUM *d = BN_new();

        if (d == NULL)
            goto err;

        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);

        /* calculate d mod (p-1) and d mod (q - 1) */
        if (!BN_mod(rsa->dmp1, d, r1, ctx)
            || !BN_mod(rsa->dmq1, d, r2, ctx)) {
            BN_free(d);
            goto err;
        }

        /* calculate CRT exponents */
        for (i = 2; i < primes; i++) {
            pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2);
            /* pinfo->d == r_i - 1 */
            if (!BN_mod(pinfo->d, d, pinfo->d, ctx)) {
                BN_free(d);
                goto err;
            }
        }

        /* We MUST free d before any further use of rsa->d */
        BN_free(d);
    }

    {
        BIGNUM *p = BN_new();

        if (p == NULL)
            goto err;
        BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);

        /* calculate inverse of q mod p */
        if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
            BN_free(p);
            goto err;
        }

        /* calculate CRT coefficient for other primes */
        for (i = 2; i < primes; i++) {
            pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2);
            BN_with_flags(p, pinfo->r, BN_FLG_CONSTTIME);
            if (!BN_mod_inverse(pinfo->t, pinfo->pp, p, ctx)) {
                BN_free(p);
                goto err;
            }
        }

        /* We MUST free p before any further use of rsa->p */
        BN_free(p);
    }

    ok = 1;
 err:
    if (ok == -1) {
        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
        ok = 0;
    }
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    return ok;
}

ENEA — Copyright (C), ENEA. License: GNU AGPLv3+.
Legal notes  ::  JavaScript license information ::  Web API

back to top