static guchar *_make_key_deriv(const gchar *passphrase, guint rounds, guint length) { guchar *kd, *salt; gchar *saltpref = prefs_common_get_prefs()->master_passphrase_salt; gsize saltlen; gint ret; /* Grab our salt, generating and saving a new random one if needed. */ if (saltpref == NULL || strlen(saltpref) == 0) { _generate_salt(); saltpref = prefs_common_get_prefs()->master_passphrase_salt; } salt = g_base64_decode(saltpref, &saltlen); kd = g_malloc0(length); START_TIMING("PBKDF2"); ret = pkcs5_pbkdf2(passphrase, strlen(passphrase), salt, saltlen, kd, length, rounds); END_TIMING(); g_free(salt); if (ret == 0) { return kd; } g_free(kd); return NULL; }
/* PBKDF */ int crypt_pbkdf(const char *kdf, const char *hash, const char *password, size_t password_length, const char *salt, size_t salt_length, char *key, size_t key_length, unsigned int iterations) { const char *hash_name = crypt_hash_compat_name(hash, NULL); #if USE_INTERNAL_PBKDF2 if (!kdf || strncmp(kdf, "pbkdf2", 6)) return -EINVAL; return pkcs5_pbkdf2(hash_name, password, password_length, salt, salt_length, iterations, key_length, key, 0); #else /* USE_INTERNAL_PBKDF2 */ int hash_id = gcry_md_map_name(hash_name); int kdf_id; if (!hash_id) return -EINVAL; if (kdf && !strncmp(kdf, "pbkdf2", 6)) kdf_id = GCRY_KDF_PBKDF2; else return -EINVAL; if (gcry_kdf_derive(password, password_length, kdf_id, hash_id, salt, salt_length, iterations, key_length, key)) return -EINVAL; return 0; #endif /* USE_INTERNAL_PBKDF2 */ }
/* PBKDF */ int crypt_pbkdf(const char *kdf, const char *hash, const char *password, size_t password_length, const char *salt, size_t salt_length, char *key, size_t key_length, uint32_t iterations, uint32_t memory, uint32_t parallel) { struct hash_alg *ha; if (!kdf) return -EINVAL; if (!strcmp(kdf, "pbkdf2")) { ha = _get_alg(hash); if (!ha) return -EINVAL; return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length, iterations, key_length, key, ha->block_length); } else if (!strncmp(kdf, "argon2", 6)) { return argon2(kdf, password, password_length, salt, salt_length, key, key_length, iterations, memory, parallel); } return -EINVAL; }
long_hash pkcs5_pbkdf2_hmac_sha512(data_slice passphrase, data_slice salt, size_t iterations) { long_hash hash; const auto result = pkcs5_pbkdf2(passphrase.data(), passphrase.size(), salt.data(), salt.size(), hash.data(), hash.size(), iterations); if (result != 0) throw std::bad_alloc(); return hash; }
/* PBKDF */ int crypt_pbkdf(const char *kdf, const char *hash, const char *password, size_t password_length, const char *salt, size_t salt_length, char *key, size_t key_length, unsigned int iterations) { struct hash_alg *ha = _get_alg(hash); if (!ha || !kdf || strncmp(kdf, "pbkdf2", 6)) return -EINVAL; return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length, iterations, key_length, key, ha->block_length); }
int pkcs5_pbkdf(enum pkcs5_pbkdf_mode mode, const struct hash_method *hash, const unsigned char *password, size_t password_len, const unsigned char *salt, size_t salt_len, unsigned int iterations, uint32_t dk_len, buffer_t *result) { if (mode == PKCS5_PBKDF1) return pkcs5_pbkdf1(hash,password,password_len, salt,salt_len,iterations,dk_len,result); else if (mode == PKCS5_PBKDF2) return pkcs5_pbkdf2(hash,password,password_len, salt,salt_len,iterations,dk_len,result); i_unreached(); }
static int pkcs5_pbkdf2_time(size_t dkLen, size_t c) { struct rusage start; struct rusage end; int ret; u_int8_t *r = NULL; u_int8_t P[CAL_PASSLEN]; u_int8_t S[CAL_SALTLEN]; (void)getrusage(RUSAGE_SELF, &start); /* XXX compat flag at end to be removed when _OLD keygen method is */ ret = pkcs5_pbkdf2(&r, dkLen, P, sizeof(P), S, sizeof(S), c, 0); if (ret) return ret; (void)getrusage(RUSAGE_SELF, &end); free(r); return (end.ru_utime.tv_sec - start.ru_utime.tv_sec) * 1000000 + (end.ru_utime.tv_usec - start.ru_utime.tv_usec); }
PSCryptor::PSCryptor (const char *password) { memset (fDerivedKey, 0, sizeof (fDerivedKey)); const char* salt = "Adobe Photoshop"; u_int iterations = 1000; // We use the PKCS#5 PBKDF2 standard to create raw key bytes from a password string. // PBKDF2 requires us to specify a salt value and an iteration count. These values must be consistent across // all implementations of this code, even when it's ported to other operating systems. // We choose "Adobe Photoshop" as the salt and 1000 iterations. // We need to tell PBKDF2 how many bytes of key data to generate. Since we're going to use 3DES as the encryption // algorithm, we choose 24 bytes (the size of a 3DES key). If we change the key algorithm in the future, we will // also have to change this value as well. // Call the pkcs5_pbkdf2 function taken from OpenBSD (public domain license) to perform the key byte generation pkcs5_pbkdf2(password, (size_t)strlen(password), salt, (size_t)strlen(salt), fDerivedKey, kPBKDKeyLength, iterations ); #if _WIN32 fSessionKey = GetSessionKey (fDerivedKey); #endif }
char * get_pkcs_key(char *arg, char *saltopt) { char passphrase[128]; char saltbuf[128], saltfilebuf[PATH_MAX]; char *key = NULL; char *saltfile; const char *errstr; int rounds; rounds = strtonum(arg, 1000, INT_MAX, &errstr); if (errstr) err(1, "rounds: %s", errstr); bzero(passphrase, sizeof(passphrase)); if (readpassphrase("Encryption key: ", passphrase, sizeof(passphrase), RPP_REQUIRE_TTY) == NULL) errx(1, "Unable to read passphrase"); if (saltopt) saltfile = saltopt; else { printf("Salt file: "); fflush(stdout); saltfile = fgets(saltfilebuf, sizeof(saltfilebuf), stdin); if (saltfile) saltfile[strcspn(saltfile, "\n")] = '\0'; } if (!saltfile || saltfile[0] == '\0') { warnx("Skipping salt file, insecure"); memset(saltbuf, 0, sizeof(saltbuf)); } else { int fd; fd = open(saltfile, O_RDONLY); if (fd == -1) { int *s; fprintf(stderr, "Salt file not found, attempting to " "create one\n"); fd = open(saltfile, O_RDWR|O_CREAT|O_EXCL, 0600); if (fd == -1) err(1, "Unable to create salt file: '%s'", saltfile); for (s = (int *)saltbuf; s < (int *)(saltbuf + sizeof(saltbuf)); s++) *s = arc4random(); if (write(fd, saltbuf, sizeof(saltbuf)) != sizeof(saltbuf)) err(1, "Unable to write salt file: '%s'", saltfile); fprintf(stderr, "Salt file created as '%s'\n", saltfile); } else { if (read(fd, saltbuf, sizeof(saltbuf)) != sizeof(saltbuf)) err(1, "Unable to read salt file: '%s'", saltfile); } close(fd); } if ((key = calloc(1, BLF_MAXUTILIZED)) == NULL) err(1, NULL); if (pkcs5_pbkdf2(passphrase, sizeof(passphrase), saltbuf, sizeof (saltbuf), key, BLF_MAXUTILIZED, rounds)) errx(1, "pkcs5_pbkdf2 failed"); memset(passphrase, 0, sizeof(passphrase)); return (key); }
void derive_key_pkcs(int rounds, u_int8_t *key, size_t keysz, u_int8_t *salt, size_t saltsz, char *prompt, int verify) { FILE *f; size_t pl; struct stat sb; char passphrase[1024], verifybuf[1024]; if (!key) errx(1, "Invalid key"); if (!salt) errx(1, "Invalid salt"); if (rounds < 1000) errx(1, "Too few rounds: %d", rounds); /* get passphrase */ if (password && verify) errx(1, "can't specify passphrase file during initial " "creation of crypto volume"); if (password) { if ((f = fopen(password, "r")) == NULL) err(1, "invalid passphrase file"); if (fstat(fileno(f), &sb) == -1) err(1, "can't stat passphrase file"); if (sb.st_uid != 0) errx(1, "passphrase file must be owned by root"); if ((sb.st_mode & ~S_IFMT) != (S_IRUSR | S_IWUSR)) errx(1, "passphrase file has the wrong permissions"); if (fgets(passphrase, sizeof(passphrase), f) == NULL) err(1, "can't read passphrase file"); pl = strlen(passphrase); if (pl > 0 && passphrase[pl - 1] == '\n') passphrase[pl - 1] = '\0'; else errx(1, "invalid passphrase length"); fclose(f); } else { if (readpassphrase(prompt, passphrase, sizeof(passphrase), rpp_flag) == NULL) errx(1, "unable to read passphrase"); } if (verify) { /* request user to re-type it */ if (readpassphrase("Re-type passphrase: ", verifybuf, sizeof(verifybuf), rpp_flag) == NULL) { memset(passphrase, 0, sizeof(passphrase)); errx(1, "unable to read passphrase"); } if ((strlen(passphrase) != strlen(verifybuf)) || (strcmp(passphrase, verifybuf) != 0)) { memset(passphrase, 0, sizeof(passphrase)); memset(verifybuf, 0, sizeof(verifybuf)); errx(1, "Passphrases did not match"); } /* forget the re-typed one */ memset(verifybuf, 0, strlen(verifybuf)); } /* derive key from passphrase */ if (pkcs5_pbkdf2(passphrase, strlen(passphrase), salt, saltsz, key, keysz, rounds) != 0) errx(1, "pbkdf2 failed"); /* forget passphrase */ memset(passphrase, 0, sizeof(passphrase)); return; }