/* * 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; }
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; }
bignum make_string_bn(ssh_string string){ bignum bn = NULL; unsigned int len = ssh_string_len(string); #ifdef DEBUG_CRYPTO fprintf(stderr, "Importing a %d bits, %d bytes object ...\n", len * 8, len); #endif /* DEBUG_CRYPTO */ #ifdef HAVE_LIBGCRYPT bignum_bin2bn(string->data, len, &bn); #elif defined HAVE_LIBCRYPTO bn = bignum_bin2bn(string->data, len, NULL); #endif return bn; }
void make_string_bn_inplace(ssh_string string, bignum bnout) { unsigned int len = ssh_string_len(string); #ifdef HAVE_LIBGCRYPT /* XXX: FIXME as needed for LIBGCRYPT ECDSA codepaths. */ (void) len; (void) bnout; #elif defined HAVE_LIBCRYPTO bignum_bin2bn(string->data, len, bnout); #endif }
bignum ssh_make_string_bn(ssh_string string) { bignum bn = NULL; size_t len = ssh_string_len(string); #ifdef DEBUG_CRYPTO fprintf(stderr, "Importing a %zu bits, %zu bytes object ...\n", len * 8, len); #endif /* DEBUG_CRYPTO */ bignum_bin2bn(string->data, len, &bn); return bn; }
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 rc; 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) { rc = 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 { rc = EC_POINT_oct2point(group, pubkey, ssh_string_data(session->next_crypto->ecdh_server_pubkey), ssh_string_len(session->next_crypto->ecdh_server_pubkey), ctx); } bignum_ctx_free(ctx); if (rc <= 0) { EC_POINT_clear_free(pubkey); return -1; } buffer = malloc(len); if (buffer == NULL) { EC_POINT_clear_free(pubkey); return -1; } rc = ECDH_compute_key(buffer, len, pubkey, session->next_crypto->ecdh_privkey, NULL); EC_POINT_clear_free(pubkey); if (rc <= 0) { free(buffer); return -1; } bignum_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 return 0; }