int ssh_mbedcry_rand(bignum rnd, int bits, int top, int bottom) { size_t len; int rc; int i; if (bits <= 0) { return 0; } len = bits / 8 + 1; rc = mbedtls_mpi_fill_random(rnd, len, mbedtls_ctr_drbg_random, &ssh_mbedtls_ctr_drbg); if (rc != 0) { return 0; } for (i = len * 8 - 1; i >= bits; i--) { rc = mbedtls_mpi_set_bit(rnd, i, 0); if (rc != 0) { return 0; } } if (top == 0) { rc = mbedtls_mpi_set_bit(rnd, bits - 1, 0); } if (top == 1) { if (bits < 2) { return 0; } rc = mbedtls_mpi_set_bit(rnd, bits - 2, 0); if (rc != 0) { return 0; } } if (bottom) { rc = mbedtls_mpi_set_bit(rnd, 0, 1); if (rc != 0) { return 0; } } return 1; }
static int twoexpt(void *a, int n) { if (mbedtls_mpi_set_bit(a, n, 1)) return CRYPT_MEM; return CRYPT_OK; }
/* Calculate Rinv = RR^2 mod M, where: * * R = b^n where b = 2^32, n=num_words, * R = 2^N (where N=num_bits) * RR = R^2 = 2^(2*N) (where N=num_bits=num_words*32) * * This calculation is computationally expensive (mbedtls_mpi_mod_mpi) * so caller should cache the result where possible. * * DO NOT call this function while holding esp_mpi_acquire_hardware(). * */ static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words) { int ret; size_t num_bits = num_words * 32; mbedtls_mpi RR; mbedtls_mpi_init(&RR); MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&RR, num_bits * 2, 1)); MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(Rinv, &RR, M)); cleanup: mbedtls_mpi_free(&RR); return ret; }