diff --git a/src/crypto/crypto_gnutls.c b/src/crypto/crypto_gnutls.c index 7ab54dfe0..20cbc3518 100644 --- a/src/crypto/crypto_gnutls.c +++ b/src/crypto/crypto_gnutls.c @@ -163,3 +163,38 @@ void aes_decrypt_deinit(void *ctx) gcry_cipher_close(hd); } #endif /* EAP_TLS_FUNCS */ + + +int crypto_mod_exp(const u8 *base, size_t base_len, + const u8 *power, size_t power_len, + const u8 *modulus, size_t modulus_len, + u8 *result, size_t *result_len) +{ + gcry_mpi_t bn_base = NULL, bn_exp = NULL, bn_modulus = NULL, + bn_result = NULL; + int ret = -1; + + if (gcry_mpi_scan(&bn_base, GCRYMPI_FMT_USG, base, base_len, NULL) != + GPG_ERR_NO_ERROR || + gcry_mpi_scan(&bn_exp, GCRYMPI_FMT_USG, power, power_len, NULL) != + GPG_ERR_NO_ERROR || + gcry_mpi_scan(&bn_modulus, GCRYMPI_FMT_USG, modulus, modulus_len, + NULL) != GPG_ERR_NO_ERROR) + goto error; + bn_result = gcry_mpi_new(modulus_len * 8); + + gcry_mpi_powm(bn_result, bn_base, bn_exp, bn_modulus); + + if (gcry_mpi_print(GCRYMPI_FMT_USG, result, *result_len, result_len, + bn_result) != GPG_ERR_NO_ERROR) + goto error; + + ret = 0; + +error: + gcry_mpi_release(bn_base); + gcry_mpi_release(bn_exp); + gcry_mpi_release(bn_modulus); + gcry_mpi_release(bn_result); + return ret; +}