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); }
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); }