void * decryption_func(void *arg)
{
  struct decryption_func_locals *dfargs;
  unsigned char *pwd, *key, *iv, *out;
  unsigned int pwd_len, len, out_len1, out_len2;
  int ret, found;
  EVP_CIPHER_CTX *ctx;

  dfargs = (struct decryption_func_locals *) arg;

  key = (unsigned char *) malloc(EVP_CIPHER_key_length(cipher));
  iv = (unsigned char *) malloc(EVP_CIPHER_iv_length(cipher));
  out = (unsigned char *) malloc(data_len + EVP_CIPHER_block_size(cipher));
  ctx = EVP_CIPHER_CTX_new();
  if((key == NULL) || (iv == NULL) || (out == NULL) || (ctx == NULL))
  {
    fprintf(stderr, "Error: memory allocation failed.\n\n");
    exit(EXIT_FAILURE);
  }

  do
  {
    if(dictionary == NULL)
    {
      if(binary)
        ret = generate_next_binary_password(&pwd, &pwd_len);
      else
        ret = generate_next_password(&pwd, &pwd_len);          
    }
    else
      ret = read_dictionary_line(&pwd, &pwd_len);
    if(ret == 0)
      break;

    /* Decrypt data with password */
    if(no_salt)
      EVP_BytesToKey(cipher, digest, NULL, pwd, pwd_len, 1, key, iv);
    else
      EVP_BytesToKey(cipher, digest, salt, pwd, pwd_len, 1, key, iv);
    EVP_DecryptInit(ctx, cipher, key, iv);
    EVP_DecryptUpdate(ctx, out, &out_len1, data, data_len);
    ret = EVP_DecryptFinal(ctx, out + out_len1, &out_len2);
    if(no_error || (ret == 1))
    {
      if(magic == NULL)
        found = valid_data(out, out_len1 + out_len2);
      else
        found = !strncmp(out, magic, strlen(magic));
    }
    else
      found = 0;

    if(found)
    {
      /* We have a positive result */
      handle_signal(SIGUSR1); /* Print some stats */
      pthread_mutex_lock(&found_password_lock);
      found_password++;
      printf("Password candidate: %s\n", pwd);
      if(only_one_password)
        stop = 1;
      pthread_mutex_unlock(&found_password_lock);
    }
    dfargs->counter++;

    EVP_CIPHER_CTX_cleanup(ctx);

    if(limit > 0)
    {
      pthread_mutex_lock(&found_password_lock);
      count_limit++;
      if(count_limit >= limit)
      {
        fprintf(stderr, "Maximum number of passphrases tested, aborting.\n");
        stop = 1;
      }
      pthread_mutex_unlock(&found_password_lock);
    }

    free(pwd);
  }
  while(stop == 0);

  EVP_CIPHER_CTX_free(ctx);
  free(out);
  free(iv);
  free(key);

  pthread_exit(NULL);
}
void restore_state()
{
  unsigned int i, n;
  unsigned long long int total_ops = 0;
  unsigned long long int run_time;
  unsigned char *line;
  FILE *state = fopen(state_file, "r");

  if(state == NULL)
  {
    fprintf(stderr, "Warning: can't open state file, state not restored, a new file will be created.\n\n");
    return;
  }

  fprintf(stderr, "Warning: restoring state, ignoring options -B, -b, -e, -f, -l, -m and -s.\n\n");

  if(dictionary != NULL)
    fclose(dictionary);

  if((fscanf(state, "openssl %ms\n", &line) != 1)
     || (fscanf(state, "time %llu\n", &run_time) != 1))
  {
    fprintf(stderr, "Error: parsing the state file failed.\n\n");
    exit(EXIT_FAILURE);
  }
  free(line);
  start_time = time(NULL) - run_time;

  if(fscanf(state, "bruteforce %u %u\n", &min_len, &max_len) == 2)
  {
    dictionary = state;

    if(fscanf(state, "binary %ms\n", &binary) == 1)
      charset_len = strlen(binary_charset);
    else
    {
      if((read_dictionary_line(&line, &n) == 0) || (n < 8))
      {
        fprintf(stderr, "Error: parsing the state file failed.\n\n");
        exit(EXIT_FAILURE);
      }
      charset_len = mbstowcs(NULL, line + 8, 0);
      if(charset_len == 0)
      {
        fprintf(stderr, "Error: charset must have at least one character.\n\n");
        exit(EXIT_FAILURE);
      }
      if(charset_len == (unsigned int) -1)
      {
        fprintf(stderr, "Error: invalid character in charset.\n\n");
        exit(EXIT_FAILURE);
      }
      charset = (wchar_t *) calloc(charset_len + 1, sizeof(wchar_t));
      if(charset == NULL)
      {
        fprintf(stderr, "Error: memory allocation failed.\n\n");
        exit(EXIT_FAILURE);
      }
      mbstowcs(charset, line + 8, charset_len + 1);
    }

    if((read_dictionary_line(&line, &n) == 0) || (n < 7))
    {
      fprintf(stderr, "Error: parsing the state file failed.\n\n");
      exit(EXIT_FAILURE);
    }
    prefix_len = mbstowcs(NULL, line + 7, 0);
    if(prefix_len == (unsigned int) -1)
    {
      fprintf(stderr, "Error: invalid character in prefix.\n\n");
      exit(EXIT_FAILURE);
    }
    prefix = (wchar_t *) calloc(prefix_len + 1, sizeof(wchar_t));
    if(prefix == NULL)
    {
      fprintf(stderr, "Error: memory allocation failed.\n\n");
      exit(EXIT_FAILURE);
    }
    mbstowcs(prefix, line + 7, prefix_len + 1);
    if(binary)
      prefix_len = wcstombs(NULL, prefix, 0);

    if((read_dictionary_line(&line, &n) == 0) || (n < 7))
    {
      fprintf(stderr, "Error: parsing the state file failed.\n\n");
      exit(EXIT_FAILURE);
    }
    suffix_len = mbstowcs(NULL, line + 7, 0);
    if(suffix_len == (unsigned int) -1)
    {
      fprintf(stderr, "Error: invalid character in suffix.\n\n");
      exit(EXIT_FAILURE);
    }
    suffix = (wchar_t *) calloc(suffix_len + 1, sizeof(wchar_t));
    if(suffix == NULL)
    {
      fprintf(stderr, "Error: memory allocation failed.\n\n");
      exit(EXIT_FAILURE);
    }
    mbstowcs(suffix, line + 7, suffix_len + 1);
    if(binary)
      suffix_len = wcstombs(NULL, suffix, 0);

    dictionary = NULL;

    if(fscanf(state, "%llu\n", &total_ops) != 1)
    {
      fprintf(stderr, "Error: parsing the state file failed.\n\n");
      exit(EXIT_FAILURE);
    }
    thread_locals[0].counter = total_ops;

    if(fscanf(state, "%u\n", &len) != 1)
    {
      fprintf(stderr, "Error: parsing the state file failed.\n\n");
      exit(EXIT_FAILURE);
    }

    tab = (unsigned int *) calloc(len + 1, sizeof(unsigned int));
    if(tab == NULL)
    {
      fprintf(stderr, "Error: memory allocation failed.\n\n");
      exit(EXIT_FAILURE);
    }
    for(i = 0; i < len; i++)
      if(fscanf(state, "%u ", &tab[i]) != 1)
      {
        fprintf(stderr, "Error: parsing the state file failed.\n\n");
        exit(EXIT_FAILURE);
      }
  }
  else if(fscanf(state, "dictionary %ms\n", &dictionary_file) == 1)
  {
    if(fscanf(state, "%llu\n", &total_ops) != 1)
    {
      fprintf(stderr, "Error: parsing the state file failed.\n\n");
      exit(EXIT_FAILURE);
    }
    thread_locals[0].counter = total_ops;

    dictionary = fopen(dictionary_file, "r");
    if(dictionary == NULL)
    {
      fprintf(stderr, "Error: can't open dictionary file.\n\n");
      exit(EXIT_FAILURE);
    }

    for(i = 0; i < total_ops; i++)
      read_dictionary_line(&line, &n);
  }
  else
  {
    fprintf(stderr, "Error: parsing the state file failed.\n\n");
    exit(EXIT_FAILURE);
  }

  fclose(state);
}
Пример #3
0
void * decryption_func_dictionary(void *arg)
{
  struct decryption_func_locals *dfargs;
  unsigned char *pwd, *key, *iv, *masterkey, *seckey, hash[32];
  unsigned int pwd_len, masterkey_len1, masterkey_len2, seckey_len1, seckey_len2;
  int ret;
  EVP_CIPHER_CTX ctx;

  dfargs = (struct decryption_func_locals *) arg;
  sha256d(pubkey, pubkey_len, hash);
  key = (unsigned char *) malloc(EVP_CIPHER_key_length(cipher));
  iv = (unsigned char *) malloc(EVP_CIPHER_iv_length(cipher));
  masterkey = (unsigned char *) malloc(encrypted_masterkey_len + EVP_CIPHER_block_size(EVP_aes_256_cbc()));
  seckey = (unsigned char *) malloc(encrypted_seckey_len + EVP_CIPHER_block_size(EVP_aes_256_cbc()));
  if((key == NULL) || (iv == NULL) || (masterkey == NULL) || (seckey == NULL))
    {
      fprintf(stderr, "Error: memory allocation failed.\n\n");
      exit(EXIT_FAILURE);
    }

  do
    {
      ret = read_dictionary_line(&pwd, &pwd_len);
      if(ret == 0)
        break;

      /* Decrypt the master key with the password */
      EVP_BytesToKey(cipher, digest, salt, pwd, pwd_len, rounds, key, iv);
      EVP_DecryptInit(&ctx, EVP_aes_256_cbc(), key, iv);
      EVP_DecryptUpdate(&ctx, masterkey, &masterkey_len1, encrypted_masterkey, encrypted_masterkey_len);
      ret = EVP_DecryptFinal(&ctx, masterkey + masterkey_len1, &masterkey_len2);
      dfargs->counter++;
      if(ret == 1)
        {
          /* Decrypt the secret key with the master key */
          EVP_CIPHER_CTX_cleanup(&ctx);
          EVP_DecryptInit(&ctx, EVP_aes_256_cbc(), masterkey, hash);
          EVP_DecryptUpdate(&ctx, seckey, &seckey_len1, encrypted_seckey, encrypted_seckey_len);
          ret = EVP_DecryptFinal(&ctx, seckey + seckey_len1, &seckey_len2);
          if((ret == 1) && valid_seckey(seckey, seckey_len1 + seckey_len2, pubkey, pubkey_len))
            {
              /* We have a positive result */
              handle_signal(SIGUSR1); /* Print some stats */
              pthread_mutex_lock(&found_password_lock);
              found_password = 1;
              printf("Password found: %s\n", pwd);
              stop = 1;
              pthread_mutex_unlock(&found_password_lock);
            }
        }
      EVP_CIPHER_CTX_cleanup(&ctx);

      free(pwd);
    }
  while(stop == 0);

  free(masterkey);
  free(seckey);
  free(iv);
  free(key);

  pthread_exit(NULL);
}