aboutsummaryrefslogtreecommitdiff
path: root/src/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kex.c')
-rw-r--r--src/kex.c78
1 files changed, 20 insertions, 58 deletions
diff --git a/src/kex.c b/src/kex.c
index 1aaa4154..750996b3 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -1196,7 +1196,7 @@ int ssh_make_sessionid(ssh_session session)
case SSH_KEX_DH_GEX_SHA1:
#endif /* WITH_GEX */
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
- session->next_crypto->mac_type = SSH_MAC_SHA1;
+ session->next_crypto->digest_type = SSH_KDF_SHA1;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if (session->next_crypto->secret_hash == NULL) {
ssh_set_error_oom(session);
@@ -1212,7 +1212,7 @@ int ssh_make_sessionid(ssh_session session)
case SSH_KEX_DH_GEX_SHA256:
#endif /* WITH_GEX */
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
- session->next_crypto->mac_type = SSH_MAC_SHA256;
+ session->next_crypto->digest_type = SSH_KDF_SHA256;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if (session->next_crypto->secret_hash == NULL) {
ssh_set_error_oom(session);
@@ -1223,7 +1223,7 @@ int ssh_make_sessionid(ssh_session session)
break;
case SSH_KEX_ECDH_SHA2_NISTP384:
session->next_crypto->digest_len = SHA384_DIGEST_LENGTH;
- session->next_crypto->mac_type = SSH_MAC_SHA384;
+ session->next_crypto->digest_type = SSH_KDF_SHA384;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if (session->next_crypto->secret_hash == NULL) {
ssh_set_error_oom(session);
@@ -1236,7 +1236,7 @@ int ssh_make_sessionid(ssh_session session)
case SSH_KEX_DH_GROUP18_SHA512:
case SSH_KEX_ECDH_SHA2_NISTP521:
session->next_crypto->digest_len = SHA512_DIGEST_LENGTH;
- session->next_crypto->mac_type = SSH_MAC_SHA512;
+ session->next_crypto->digest_type = SSH_KDF_SHA512;
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if (session->next_crypto->secret_hash == NULL) {
ssh_set_error_oom(session);
@@ -1346,60 +1346,18 @@ int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie)
return 0;
}
-static int generate_one_key(ssh_string k, struct ssh_crypto_struct *crypto,
- unsigned char *output, char letter,
- size_t requested_size)
-{
- ssh_mac_ctx ctx;
- size_t size = crypto->digest_len;
- unsigned char digest[size];
-
- ctx = ssh_mac_ctx_init(crypto->mac_type);
- if (ctx == NULL) {
- return -1;
- }
-
- ssh_mac_update(ctx, k, ssh_string_len(k) + 4);
- ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
- ssh_mac_update(ctx, &letter, 1);
- ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
- ssh_mac_final(digest, ctx);
-
- if (requested_size < size) {
- size = requested_size;
- }
- memcpy(output, digest, size);
-
- while (requested_size > size) {
- ctx = ssh_mac_ctx_init(crypto->mac_type);
- if (ctx == NULL) {
- return -1;
- }
- ssh_mac_update(ctx, k, ssh_string_len(k) + 4);
- ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
- ssh_mac_update(ctx, output, size);
- ssh_mac_final(digest, ctx);
- if (requested_size < size + crypto->digest_len) {
- memcpy(output+size, digest, requested_size - size);
- } else {
- memcpy(output+size, digest, crypto->digest_len);
- }
- size += crypto->digest_len;
- }
-
- return 0;
-}
-
int ssh_generate_session_keys(ssh_session session)
{
ssh_string k_string = NULL;
struct ssh_crypto_struct *crypto = session->next_crypto;
+ unsigned char *key = NULL;
unsigned char *IV_cli_to_srv = NULL;
unsigned char *IV_srv_to_cli = NULL;
unsigned char *enckey_cli_to_srv = NULL;
unsigned char *enckey_srv_to_cli = NULL;
unsigned char *intkey_cli_to_srv = NULL;
unsigned char *intkey_srv_to_cli = NULL;
+ size_t key_len = 0;
size_t IV_len = 0;
size_t enckey_cli_to_srv_len = 0;
size_t enckey_srv_to_cli_len = 0;
@@ -1412,6 +1370,10 @@ int ssh_generate_session_keys(ssh_session session)
ssh_set_error_oom(session);
goto error;
}
+ /* See RFC4251 Section 5 for the definition of mpint which is the
+ * encoding we need to use for key in the SSH KDF */
+ key = (unsigned char *)k_string;
+ key_len = ssh_string_len(k_string) + 4;
IV_len = crypto->digest_len;
if (session->client) {
@@ -1440,33 +1402,33 @@ int ssh_generate_session_keys(ssh_session session)
}
/* IV */
- rc = generate_one_key(k_string, crypto, IV_cli_to_srv, 'A', IV_len);
+ rc = ssh_kdf(crypto, key, key_len, 'A', IV_cli_to_srv, IV_len);
if (rc < 0) {
goto error;
}
- rc = generate_one_key(k_string, crypto, IV_srv_to_cli, 'B', IV_len);
+ rc = ssh_kdf(crypto, key, key_len, 'B', IV_srv_to_cli, IV_len);
if (rc < 0) {
goto error;
}
/* Encryption Key */
- rc = generate_one_key(k_string, crypto, enckey_cli_to_srv, 'C',
- enckey_cli_to_srv_len);
+ rc = ssh_kdf(crypto, key, key_len, 'C', enckey_cli_to_srv,
+ enckey_cli_to_srv_len);
if (rc < 0) {
goto error;
}
- rc = generate_one_key(k_string, crypto, enckey_srv_to_cli, 'D',
- enckey_srv_to_cli_len);
+ rc = ssh_kdf(crypto, key, key_len, 'D', enckey_srv_to_cli,
+ enckey_srv_to_cli_len);
if (rc < 0) {
goto error;
}
/* Integrity Key */
- rc = generate_one_key(k_string, crypto, intkey_cli_to_srv, 'E',
- intkey_cli_to_srv_len);
+ rc = ssh_kdf(crypto, key, key_len, 'E', intkey_cli_to_srv,
+ intkey_cli_to_srv_len);
if (rc < 0) {
goto error;
}
- rc = generate_one_key(k_string, crypto, intkey_srv_to_cli, 'F',
- intkey_srv_to_cli_len);
+ rc = ssh_kdf(crypto, key, key_len, 'F', intkey_srv_to_cli,
+ intkey_srv_to_cli_len);
if (rc < 0) {
goto error;
}