/* * This inits the values g and p which are used for DH key agreement * FIXME: Make the function thread safe by adding a semaphore or mutex. */ int ssh_crypto_init(void) { if (ssh_crypto_initialized == 0) { #ifdef HAVE_LIBGCRYPT gcry_check_version(NULL); if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0)) { gcry_control(GCRYCTL_INIT_SECMEM, 4096); gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0); } #endif g = bignum_new(); if (g == NULL) { return -1; } bignum_set_word(g,g_int); #ifdef HAVE_LIBGCRYPT bignum_bin2bn(p_group1_value, P_GROUP1_LEN, &p_group1); if (p_group1 == NULL) { bignum_free(g); g = NULL; return -1; } bignum_bin2bn(p_group14_value, P_GROUP14_LEN, &p_group14); if (p_group14 == NULL) { bignum_free(g); bignum_free(p_group1); g = NULL; p_group1 = NULL; return -1; } #elif defined HAVE_LIBCRYPTO p_group1 = bignum_new(); if (p_group1 == NULL) { bignum_free(g); g = NULL; return -1; } bignum_bin2bn(p_group1_value, P_GROUP1_LEN, p_group1); p_group14 = bignum_new(); if (p_group14 == NULL) { bignum_free(g); bignum_free(p_group1); g = NULL; p_group1 = NULL; return -1; } bignum_bin2bn(p_group14_value, P_GROUP14_LEN, p_group14); OpenSSL_add_all_algorithms(); #endif ssh_crypto_initialized = 1; } return 0; }
char *ssh_gcry_bn2dec(bignum bn) { bignum bndup, num, ten; char *ret; int count, count2; int size, rsize; char decnum; size = gcry_mpi_get_nbits(bn) * 3; rsize = size / 10 + size / 1000 + 2; ret = malloc(rsize + 1); if (ret == NULL) { return NULL; } if (!gcry_mpi_cmp_ui(bn, 0)) { strcpy(ret, "0"); } else { ten = bignum_new(); if (ten == NULL) { SAFE_FREE(ret); return NULL; } num = bignum_new(); if (num == NULL) { SAFE_FREE(ret); bignum_safe_free(ten); return NULL; } for (bndup = gcry_mpi_copy(bn), bignum_set_word(ten, 10), count = rsize; count; count--) { gcry_mpi_div(bndup, num, bndup, ten, 0); for (decnum = 0, count2 = gcry_mpi_get_nbits(num); count2; decnum *= 2, decnum += (gcry_mpi_test_bit(num, count2 - 1) ? 1 : 0), count2--) ; ret[count - 1] = decnum + '0'; } for (count = 0; count < rsize && ret[count] == '0'; count++) ; for (count2 = 0; count2 < rsize - count; ++count2) { ret[count2] = ret[count2 + count]; } ret[count2] = 0; bignum_safe_free(num); bignum_safe_free(bndup); bignum_safe_free(ten); } return ret; }
int dh_generate_f(ssh_session session) { #ifdef HAVE_LIBCRYPTO bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } #endif session->next_crypto->f = bignum_new(); if (session->next_crypto->f == NULL) { #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return -1; } #ifdef HAVE_LIBGCRYPT bignum_mod_exp(session->next_crypto->f, g, session->next_crypto->y, select_p(session->next_crypto->kex_type)); #elif defined HAVE_LIBCRYPTO bignum_mod_exp(session->next_crypto->f, g, session->next_crypto->y, select_p(session->next_crypto->kex_type), ctx); #endif #ifdef DEBUG_CRYPTO ssh_print_bignum("f", session->next_crypto->f); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
/* used by server */ int dh_generate_e(ssh_session session) { #ifdef HAVE_LIBCRYPTO bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } #endif session->next_crypto->e = bignum_new(); if (session->next_crypto->e == NULL) { #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return -1; } #ifdef HAVE_LIBGCRYPT bignum_mod_exp(session->next_crypto->e, g, session->next_crypto->x, p); #elif defined HAVE_LIBCRYPTO bignum_mod_exp(session->next_crypto->e, g, session->next_crypto->x, p, ctx); #endif #ifdef DEBUG_CRYPTO ssh_print_bignum("e", session->next_crypto->e); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
static int ssh_curve25519_build_k(ssh_session_t * session) { ssh_curve25519_pubkey k; session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { return SSH_ERROR; } if (session->server) crypto_scalarmult(k, session->next_crypto->curve25519_privkey, session->next_crypto->curve25519_client_pubkey); else crypto_scalarmult(k, session->next_crypto->curve25519_privkey, session->next_crypto->curve25519_server_pubkey); bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k); #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif return 0; }
int dh_build_k(ssh_session session) { #ifdef HAVE_LIBCRYPTO bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } #endif session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return -1; } /* the server and clients don't use the same numbers */ #ifdef HAVE_LIBGCRYPT if(session->client) { bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, session->next_crypto->x, select_p(session->next_crypto->kex_type)); } else { bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, session->next_crypto->y, select_p(session->next_crypto->kex_type)); } #elif defined HAVE_LIBCRYPTO if (session->client) { bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, session->next_crypto->x, select_p(session->next_crypto->kex_type), ctx); } else { bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, session->next_crypto->y, select_p(session->next_crypto->kex_type), ctx); } #endif #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
static int ecdh_build_k(ssh_session session) { const EC_GROUP *group = EC_KEY_get0_group(session->next_crypto->ecdh_privkey); EC_POINT *pubkey; void *buffer; int len = (EC_GROUP_get_degree(group) + 7) / 8; bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { bignum_ctx_free(ctx); return -1; } pubkey = EC_POINT_new(group); if (pubkey == NULL) { bignum_ctx_free(ctx); return -1; } if (session->server) EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_client_pubkey), ssh_string_len(session->next_crypto->ecdh_client_pubkey),ctx); else EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_server_pubkey), ssh_string_len(session->next_crypto->ecdh_server_pubkey),ctx); buffer = malloc(len); ECDH_compute_key(buffer,len,pubkey,session->next_crypto->ecdh_privkey,NULL); EC_POINT_free(pubkey); BN_bin2bn(buffer,len,session->next_crypto->k); free(buffer); EC_KEY_free(session->next_crypto->ecdh_privkey); session->next_crypto->ecdh_privkey=NULL; #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
int main(int argc, const char *argv[]) { int a, count; bignum *big_a; count = 0; for (a = 1; a <= 10000; a++) { big_a = bignum_new(a); if (bignum_is_lychrel(big_a, 50)) { count++; } bignum_delete(big_a); } printf("%d\n", count); return 0; }
int ssh_gcry_dec2bn(bignum *bn, const char *data) { int count; *bn = bignum_new(); if (*bn == NULL) { return 0; } gcry_mpi_set_ui(*bn, 0); for (count = 0; data[count]; count++) { gcry_mpi_mul_ui(*bn, *bn, 10); gcry_mpi_add_ui(*bn, *bn, data[count] - '0'); } return count; }
/* used by server */ int dh_generate_y(ssh_session session) { session->next_crypto->y = bignum_new(); if (session->next_crypto->y == NULL) { return -1; } #ifdef HAVE_LIBGCRYPT bignum_rand(session->next_crypto->y, 128); #elif defined HAVE_LIBCRYPTO bignum_rand(session->next_crypto->y, 128, 0, -1); #endif /* not harder than this */ #ifdef DEBUG_CRYPTO ssh_print_bignum("y", session->next_crypto->y); #endif return 0; }
/** @brief generates a random integer between 0 and max * @returns 1 in case of success, 0 otherwise */ int ssh_gcry_rand_range(bignum dest, bignum max) { size_t bits; bignum rnd; int rc; bits = bignum_num_bits(max) + 64; rnd = bignum_new(); if (rnd == NULL) { return 0; } rc = bignum_rand(rnd, bits); if (rc != 1) { return rc; } gcry_mpi_mod(dest, rnd, max); bignum_safe_free(rnd); return 1; }