示例#1
0
文件: password.c 项目: Tux/claws-mail
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;
}
示例#2
0
/* 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;
}
示例#4
0
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;
}
示例#5
0
/* 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);
}
示例#6
0
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();
}
示例#7
0
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);
}
示例#8
0
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
}
示例#9
0
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);
}
示例#10
0
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;
}