Beispiel #1
0
int
init_crypto(crypto_ctx_t *cctx, uchar_t *pwd, int pwd_len, int crypto_alg,
	    uchar_t *salt, int saltlen, uint64_t nonce, int enc_dec)
{
	if (crypto_alg == CRYPTO_ALG_AES) {
		aes_ctx_t *actx = malloc(sizeof (aes_ctx_t));

		if (enc_dec) {
			/*
			 * Encryption init.
			 */
			cctx->salt = malloc(32);
			salt = cctx->salt;
			cctx->saltlen = 32;
			if (RAND_status() != 1 || RAND_bytes(salt, 32) != 1) {
				if (geturandom_bytes(salt) != 0) {
					uchar_t sb[64];
					int b;
					struct timespec tp;

					b = 0;
					/* No good random pool is populated/available. What to do ? */
					if (clock_gettime(CLOCK_MONOTONIC, &tp) == -1) {
						time((time_t *)&sb[b]);
						b += 8;
					} else {
						uint64_t v;
						v = tp.tv_sec * 1000UL + tp.tv_nsec;
						*((uint64_t *)&sb[b]) = v;
						b += 8;
					}
					*((uint32_t *)&sb[b]) = rand();
					b += 4;
					*((uint32_t *)&sb[b]) = getpid();
					b += 4;
					compute_checksum(&sb[b], CKSUM_SHA256, sb, b);
					b = 8 + 4;
					*((uint32_t *)&sb[b]) = rand();
					compute_checksum(salt, CKSUM_SHA256, &sb[b], 32 + 4);
				}
			}

			/*
			 * Zero nonce (arg #6) since it will be generated.
			 */
			if (aes_init(actx, salt, 32, pwd, pwd_len, 0, enc_dec) != 0) {
				fprintf(stderr, "Failed to initialize AES context\n");
				return (-1);
			}
		} else {
			/*
			 * Decryption init.
			 * Pass given nonce and salt.
			 */
			if (saltlen > MAX_SALTLEN) {
				fprintf(stderr, "Salt too long. Max allowed length is %d\n",
				    MAX_SALTLEN);
				return (-1);
			}
			cctx->salt = malloc(saltlen);
			memcpy(cctx->salt, salt, saltlen);

			if (aes_init(actx, cctx->salt, saltlen, pwd, pwd_len, nonce,
			    enc_dec) != 0) {
				fprintf(stderr, "Failed to initialize AES context\n");
				return (-1);
			}
		}
		cctx->crypto_ctx = actx;
		cctx->crypto_alg = crypto_alg;
		cctx->enc_dec = enc_dec;
	} else {
		fprintf(stderr, "Unrecognized algorithm code: %d\n", crypto_alg);
		return (-1);
	}
	return (0);
}
Beispiel #2
0
int
salsa20_init(salsa20_ctx_t *ctx, uchar_t *salt, int saltlen, uchar_t *pwd, int pwd_len,
	 uchar_t *nonce, int enc)
{
	struct timespec tp;
	uint64_t tv;
	uchar_t num[25];
	uchar_t IV[32];
	uchar_t *key = ctx->pkey;

#ifndef	_USE_PBK
	int logN;
	uint32_t r, p;
	uint64_t N;

	if (XSALSA20_CRYPTO_NONCEBYTES % 8) {
		log_msg(LOG_ERR, 0, "XSALSA20_CRYPTO_NONCEBYTES is not a multiple of 8!\n");
		return (-1);
	}
	pickparams(&logN, &r, &p);
	N = (uint64_t)(1) << logN;
	if (crypto_scrypt(pwd, pwd_len, salt, saltlen, N, r, p, key, ctx->keylen)) {
		log_msg(LOG_ERR, 0, "Scrypt failed\n");
		return (-1);
	}
#else
	rv = PKCS5_PBKDF2_HMAC(pwd, pwd_len, salt, saltlen, PBE_ROUNDS, EVP_sha256(),
			       ctx->keylen, key);
	if (rv != ctx->keylen) {
		log_msg(LOG_ERR, 0, "Key size is %d bytes - should be %d bits\n", i, ctx->keylen);
		return (-1);
	}
#endif

	/*
	 * Copy the key. XSalsa20 core cipher always uses a 256-bit key. If we are using a
	 * 128-bit key then the key value is repeated twice to form a 256-bit value.
	 * This approach is based on the Salsa20 code submitted to eSTREAM. See the function
	 * ECRYPT_keysetup() in the Salsa20 submission:
	 * http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/ref/salsa20.c?rev=161&view=auto
	 * 
	 * The input values corresponding to a 256-bit key contain repeated values if key
	 * length is 128-bit.
	 */
	memcpy(ctx->key, key, ctx->keylen);
	if (ctx->keylen < XSALSA20_CRYPTO_KEYBYTES) {
		uchar_t *k;
		k = ctx->key + ctx->keylen;
		memcpy(k, key, XSALSA20_CRYPTO_KEYBYTES - ctx->keylen);
	}

	if (enc) {
		int i;
		uint64_t *n, *n1;

		// Derive 192-bit nonce
		if (RAND_status() != 1 || RAND_bytes(IV, XSALSA20_CRYPTO_NONCEBYTES) != 1) {
			if (geturandom_bytes(IV, XSALSA20_CRYPTO_NONCEBYTES) != 0) {
				if (clock_gettime(CLOCK_MONOTONIC, &tp) == -1) {
					time((time_t *)&tv);
				} else {
					tv = tp.tv_sec * 1000UL + tp.tv_nsec;
				}
				sprintf((char *)num, "%" PRIu64, tv);
				PKCS5_PBKDF2_HMAC((const char *)num, strlen((char *)num), salt,
						saltlen, PBE_ROUNDS, EVP_sha256(), 32, IV);
			}
		}
		n = (uint64_t *)IV;
		n1 = (uint64_t *)(ctx->nonce);
		for (i = 0; i < XSALSA20_CRYPTO_NONCEBYTES/8; i++) {
			*n1 = LE64(*n);
			n++;
			n1++;
		}

		// Nullify stack components
		memset(num, 0, 25);
		memset(IV, 0, 32);
		memset(&tp, 0, sizeof (tp));
		tv = 0;
	} else {
		memcpy(ctx->nonce, nonce, XSALSA20_CRYPTO_NONCEBYTES);
		memset(nonce, 0, XSALSA20_CRYPTO_NONCEBYTES);
	}
	return (0);
}