Example #1
0
File: dh.c Project: mwgoldsmith/ssh
int generate_session_keys(ssh_session session) {
  ssh_string k_string = NULL;
  struct ssh_crypto_struct *crypto = session->next_crypto;
  unsigned char *tmp;
  int rc = -1;

  k_string = make_bignum_string(crypto->k);
  if (k_string == NULL) {
    ssh_set_error_oom(session);
    goto error;
  }

  crypto->encryptIV = malloc(crypto->digest_len);
  crypto->decryptIV = malloc(crypto->digest_len);
  crypto->encryptkey = malloc(crypto->digest_len);
  crypto->decryptkey = malloc(crypto->digest_len);
  crypto->encryptMAC = malloc(crypto->digest_len);
  crypto->decryptMAC = malloc(crypto->digest_len);
  if(crypto->encryptIV == NULL || crypto->decryptIV == NULL ||
      crypto->encryptkey == NULL || crypto->decryptkey == NULL ||
      crypto->encryptMAC == NULL || crypto->decryptMAC == NULL){
    ssh_set_error_oom(session);
    goto error;
  }

  /* IV */
  if (session->client) {
    rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'A', crypto->digest_len);
    if (rc < 0) {
      goto error;
    }
    rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'B', crypto->digest_len);
    if (rc < 0) {
      goto error;
    }
  } else {
    rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'A', crypto->digest_len);
    if (rc < 0) {
      goto error;
    }
    rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'B', crypto->digest_len);
    if (rc < 0) {
      goto error;
    }
  }
  if (session->client) {
    rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'C', crypto->out_cipher->keysize / 8);
    if (rc < 0) {
      goto error;
    }
    rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'D', crypto->in_cipher->keysize / 8);
    if (rc < 0) {
      goto error;
    }
  } else {
    rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'C', crypto->in_cipher->keysize / 8);
    if (rc < 0) {
      goto error;
    }
    rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'D', crypto->out_cipher->keysize / 8);
    if (rc < 0) {
      goto error;
    }
  }

  if(session->client) {
    rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'E', hmac_digest_len(crypto->out_hmac));
    if (rc < 0) {
      goto error;
    }
    rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'F', hmac_digest_len(crypto->in_hmac));
    if (rc < 0) {
      goto error;
    }
  } else {
    rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'E', hmac_digest_len(crypto->in_hmac));
    if (rc < 0) {
      goto error;
    }
    rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'F', hmac_digest_len(crypto->out_hmac));
    if (rc < 0) {
      goto error;
    }
  }

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("Encrypt IV", crypto->encryptIV, crypto->digest_len);
  ssh_print_hexa("Decrypt IV", crypto->decryptIV, crypto->digest_len);
  ssh_print_hexa("Encryption key", crypto->encryptkey, crypto->out_cipher->keysize / 8);
  ssh_print_hexa("Decryption key", crypto->decryptkey, crypto->in_cipher->keysize / 8);
  ssh_print_hexa("Encryption MAC", crypto->encryptMAC, hmac_digest_len(crypto->out_hmac));
  ssh_print_hexa("Decryption MAC", crypto->decryptMAC, hmac_digest_len(crypto->in_hmac));
#endif

  rc = 0;
error:
  ssh_string_free(k_string);

  return rc;
}
Example #2
0
int generate_session_keys(ssh_session session) {
  ssh_string k_string = NULL;
  SHACTX ctx = NULL;
  int rc = -1;

  enter_function();

  k_string = make_bignum_string(session->next_crypto->k);
  if (k_string == NULL) {
    goto error;
  }

  /* IV */
  if (session->client) {
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->encryptIV, 'A') < 0) {
      goto error;
    }
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->decryptIV, 'B') < 0) {
      goto error;
    }
  } else {
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->decryptIV, 'A') < 0) {
      goto error;
    }
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->encryptIV, 'B') < 0) {
      goto error;
    }
  }
  if (session->client) {
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->encryptkey, 'C') < 0) {
      goto error;
    }
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->decryptkey, 'D') < 0) {
      goto error;
    }
  } else {
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->decryptkey, 'C') < 0) {
      goto error;
    }
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->encryptkey, 'D') < 0) {
      goto error;
    }
  }

  /* some ciphers need more than 20 bytes of input key */
  /* XXX verify it's ok for server implementation */
  if (session->next_crypto->out_cipher->keysize > SHA_DIGEST_LEN * 8) {
    ctx = sha1_init();
    if (ctx == NULL) {
      goto error;
    }
    sha1_update(ctx, k_string, ssh_string_len(k_string) + 4);
    sha1_update(ctx, session->next_crypto->session_id, SHA_DIGEST_LEN);
    sha1_update(ctx, session->next_crypto->encryptkey, SHA_DIGEST_LEN);
    sha1_final(session->next_crypto->encryptkey + SHA_DIGEST_LEN, ctx);
  }

  if (session->next_crypto->in_cipher->keysize > SHA_DIGEST_LEN * 8) {
    ctx = sha1_init();
    sha1_update(ctx, k_string, ssh_string_len(k_string) + 4);
    sha1_update(ctx, session->next_crypto->session_id, SHA_DIGEST_LEN);
    sha1_update(ctx, session->next_crypto->decryptkey, SHA_DIGEST_LEN);
    sha1_final(session->next_crypto->decryptkey + SHA_DIGEST_LEN, ctx);
  }
  if(session->client) {
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->encryptMAC, 'E') < 0) {
      goto error;
    }
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->decryptMAC, 'F') < 0) {
      goto error;
    }
  } else {
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->decryptMAC, 'E') < 0) {
      goto error;
    }
    if (generate_one_key(k_string, session->next_crypto->session_id,
          session->next_crypto->encryptMAC, 'F') < 0) {
      goto error;
    }
  }

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("Encrypt IV", session->next_crypto->encryptIV, SHA_DIGEST_LEN);
  ssh_print_hexa("Decrypt IV", session->next_crypto->decryptIV, SHA_DIGEST_LEN);
  ssh_print_hexa("Encryption key", session->next_crypto->encryptkey,
      session->next_crypto->out_cipher->keysize);
  ssh_print_hexa("Decryption key", session->next_crypto->decryptkey,
      session->next_crypto->in_cipher->keysize);
  ssh_print_hexa("Encryption MAC", session->next_crypto->encryptMAC, SHA_DIGEST_LEN);
  ssh_print_hexa("Decryption MAC", session->next_crypto->decryptMAC, 20);
#endif

  rc = 0;
error:
  ssh_string_free(k_string);
  leave_function();

  return rc;
}