Example #1
0
int main(void) {
	if (sodium_init() == -1) {
		return -1;
	}

	return_status status = return_status_init();

	//create buffers
	buffer_t *master_key = buffer_create_on_heap(50, 50);
	buffer_t *subkey1 = buffer_create_on_heap(60, 60);
	buffer_t *subkey2 = buffer_create_on_heap(60, 60);
	buffer_t *subkey1_copy = buffer_create_on_heap(60, 60);

	int status_int = 0;
	status_int = buffer_fill_random(master_key, master_key->buffer_length);
	if (status_int != 0) {
		throw(KEYDERIVATION_FAILED, "Failed to generate master key.");
	}
	printf("Master key:\n");
	print_hex(master_key);
	putchar('\n');

	status = derive_key(subkey1, subkey1->buffer_length, master_key, 0);
	throw_on_error(KEYDERIVATION_FAILED, "Failed to derive first subkey.");
	printf("First subkey:\n");
	print_hex(subkey1);
	putchar('\n');

	status = derive_key(subkey2, subkey2->buffer_length, master_key, 1);
	throw_on_error(KEYDERIVATION_FAILED, "Failed to derive the second subkey.");
	printf("Second subkey:\n");
	print_hex(subkey2);
	putchar('\n');

	if (buffer_compare(subkey1, subkey2) == 0) {
		throw(KEYGENERATION_FAILED, "Both subkeys are the same.");
	}

	status = derive_key(subkey1_copy, subkey1_copy->buffer_length, master_key, 0);
	throw_on_error(KEYDERIVATION_FAILED, "Failed to derive copy of the first subkey.");

	if (buffer_compare(subkey1, subkey1_copy) != 0) {
		throw(INCORRECT_DATA, "Failed to reproduce subkey.");
	}

cleanup:
	buffer_destroy_from_heap_and_null_if_valid(master_key);
	buffer_destroy_from_heap_and_null_if_valid(subkey1);
	buffer_destroy_from_heap_and_null_if_valid(subkey2);
	buffer_destroy_from_heap_and_null_if_valid(subkey1_copy);

	on_error {
		print_errors(&status);
	}
	return_status_destroy_errors(&status);

	return status.status;
}
Example #2
0
//! Use key + salt to encrypt the header, and write it to disk.
status_t
VolumeCryptContext::_WriteHeader(int fd, const uint8* key, uint32 keyLength,
	off_t headerOffset, uint8* buffer)
{
	uint8 diskKey[DISK_KEY_SIZE];
	derive_key(key, keyLength, buffer, PKCS5_SALT_SIZE, diskKey, DISK_KEY_SIZE);

	status_t status = Init(ALGORITHM_AES, MODE_XTS, diskKey, DISK_KEY_SIZE);
	if (status != B_OK)
		return status;

	true_crypt_header& header = *(true_crypt_header*)&buffer[PKCS5_SALT_SIZE];
	Encrypt((uint8*)&header, BLOCK_SIZE - PKCS5_SALT_SIZE);

	ssize_t bytesWritten = write_pos(fd, headerOffset, buffer, BLOCK_SIZE);
	if (bytesWritten < 0)
		return errno;

	// use the decrypted header to init the volume encryption

	Decrypt((uint8*)&header, BLOCK_SIZE - PKCS5_SALT_SIZE);
	SetKey(header.disk_key, sizeof(header.disk_key));

	return B_OK;
}
Example #3
0
int
kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
    const u_char *shared_secret, u_int slen)
{
	struct kex *kex = ssh->kex;
	u_char *keys[NKEYS];
	u_int i, j, mode, ctos;
	int r;

	for (i = 0; i < NKEYS; i++) {
		if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
		    shared_secret, slen, &keys[i])) != 0) {
			for (j = 0; j < i; j++)
				free(keys[j]);
			return r;
		}
	}
	for (mode = 0; mode < MODE_MAX; mode++) {
		ctos = (!kex->server && mode == MODE_OUT) ||
		    (kex->server && mode == MODE_IN);
		kex->newkeys[mode]->enc.iv  = keys[ctos ? 0 : 1];
		kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
		kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
	}
	return 0;
}
Example #4
0
/**
 * gcr_secret_exchange_receive:
 * @self: a #GcrSecretExchange object
 * @exchange: the string received
 *
 * Receive a string from the other side of secret exchange. This string will
 * have been created by gcr_secret_exchange_begin() or gcr_secret_exchange_send().
 *
 * After this call completes successfully the value returned from
 * gcr_secret_exchange_get_secret() will have changed.
 *
 * Returns: whether the string was successfully parsed and received
 */
gboolean
gcr_secret_exchange_receive (GcrSecretExchange *self,
                             const gchar *exchange)
{
	GcrSecretExchangeClass *klass;
	gchar *secret = NULL;
	gsize n_secret = 0;
	GKeyFile *input;
	gboolean ret;

	g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), FALSE);
	g_return_val_if_fail (exchange != NULL, FALSE);

	klass = GCR_SECRET_EXCHANGE_GET_CLASS (self);
	g_return_val_if_fail (klass->generate_exchange_key, FALSE);
	g_return_val_if_fail (klass->derive_transport_key, FALSE);

	gchar *string = g_strescape (exchange, "");
	g_debug ("receiving secret exchange: %s", string);
	g_free (string);

	/* Parse the input */
	input = g_key_file_new ();
	if (!g_key_file_load_from_data (input, exchange, strlen (exchange),
	                                G_KEY_FILE_NONE, NULL)) {
		g_key_file_free (input);
		g_message ("couldn't parse secret exchange data");
		return FALSE;
	}

	if (!self->pv->generated) {
		if (!(klass->generate_exchange_key) (self, GCR_SECRET_EXCHANGE_PROTOCOL_1,
		                                     &self->pv->publi, &self->pv->n_publi))
			g_return_val_if_reached (FALSE);
		self->pv->generated = TRUE;
	}

	ret = TRUE;

	if (!self->pv->derived) {
		if (!derive_key (self, input))
			ret = FALSE;
	}

	if (ret && g_key_file_has_key (input, GCR_SECRET_EXCHANGE_PROTOCOL_1, "secret", NULL))
		ret = perform_decrypt (self, input, (guchar **)&secret, &n_secret);

	if (ret) {
		egg_secure_free (self->pv->secret);
		self->pv->secret = secret;
		self->pv->n_secret = n_secret;
	}

	g_key_file_free (input);
	return ret;
}
Example #5
0
sgx_status_t key_derivation(const sgx_ec256_dh_shared_t* shared_key,
    uint16_t kdf_id,
    sgx_ec_key_128bit_t* smk_key,
    sgx_ec_key_128bit_t* sk_key,
    sgx_ec_key_128bit_t* mk_key,
    sgx_ec_key_128bit_t* vk_key)
{
    bool derive_ret = false;

    if (NULL == shared_key)
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    if (ISV_KDF_ID != kdf_id)
    {
        //fprintf(stderr, "\nError, key derivation id mismatch in [%s].", __FUNCTION__);
        return SGX_ERROR_KDF_MISMATCH;
    }

    derive_ret = derive_key(shared_key, DERIVE_KEY_SMK_SK,
        smk_key, sk_key);
    if (derive_ret != true)
    {
        //fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
        return SGX_ERROR_UNEXPECTED;
    }

    derive_ret = derive_key(shared_key, DERIVE_KEY_MK_VK,
        mk_key, vk_key);
    if (derive_ret != true)
    {
        //fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
        return SGX_ERROR_UNEXPECTED;
    }
    return SGX_SUCCESS;
}
static void crypt_all(int count)
{
	int index = 0;
#ifdef _OPENMP
#pragma omp parallel for
	for (index = 0; index < count; index++)
#endif
	{
		unsigned char master[24];
		derive_key((unsigned char *)saved_key[index],  strlen(saved_key[index]), salt_struct->salt, SALTLEN, 1000, master, 24);
		if(kcdecrypt(master, salt_struct->iv, salt_struct->ct) == 0)
			cracked[index] = 1;
		else
			cracked[index] = 0;
	}
}
Example #7
0
static void crypt_all(int count)
{
	int index;
#ifdef _OPENMP
#pragma omp parallel for default(none) private(index) shared(count, passverify, has_been_cracked, saved_key, saved_salt, mode)
#endif
	for (index = 0; index < count; index++) {
		unsigned char pwd_ver[2] = { 0 };
		unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH];
/* Derive the encryption and authetication keys and the password verifier */
		derive_key((unsigned char *)saved_key[index],
		    strlen(saved_key[index]), saved_salt, SALT_LENGTH(mode),
		    KEYING_ITERATIONS, kbuf,
		    2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);
		memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH);
		has_been_cracked[index] = !memcmp(pwd_ver, passverify, 2);
	}
}
Example #8
0
int fcrypt_init(
    int mode,                               /* the mode to be used (input)          */
    const unsigned char pwd[],              /* the user specified password (input)  */
    unsigned int pwd_len,                   /* the length of the password (input)   */
    const unsigned char salt[],             /* the salt (input)                     */
#ifdef PASSWORD_VERIFIER
    unsigned char pwd_ver[PWD_VER_LENGTH],  /* 2 byte password verifier (output)    */
#endif
    fcrypt_ctx      cx[1])                  /* the file encryption context (output) */
{
    unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH];

    if(pwd_len > MAX_PWD_LENGTH)
        return PASSWORD_TOO_LONG;

    if(mode < 1 || mode > 3)
        return BAD_MODE;

    cx->mode = mode;
    cx->pwd_len = pwd_len;
    /* initialise the encryption nonce and buffer pos   */
    cx->encr_pos = BLOCK_SIZE;

    /* if we need a random component in the encryption  */
    /* nonce, this is where it would have to be set     */
    memset(cx->nonce, 0, BLOCK_SIZE * sizeof(unsigned char));
    /* initialise for authentication			        */
    hmac_sha_begin(cx->auth_ctx);

    /* derive the encryption and authetication keys and the password verifier   */
    derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS,
                        kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);
    /* set the encryption key							*/
    aes_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx);
    /* set the authentication key						*/
    hmac_sha_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx);
#ifdef PASSWORD_VERIFIER
    memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH);
#endif
    /* clear the buffer holding the derived key values	*/
    memset(kbuf, 0, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);

    return GOOD_RETURN;
}
Example #9
0
void
kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
{
	u_char *keys[NKEYS];
	int i, mode, ctos;

	for (i = 0; i < NKEYS; i++)
		keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret);

	debug2("kex_derive_keys");
	for (mode = 0; mode < MODE_MAX; mode++) {
		current_keys[mode] = kex->newkeys[mode];
		kex->newkeys[mode] = NULL;
		ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
		current_keys[mode]->enc.iv  = keys[ctos ? 0 : 1];
		current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
		current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
	}
}
Example #10
0
File: srtp.c Project: AVbin/libav
int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
                       const char *params)
{
    uint8_t buf[30];

    ff_srtp_free(s);

    // RFC 4568
    if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") ||
        !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) {
        s->rtp_hmac_size = s->rtcp_hmac_size = 10;
    } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
        s->rtp_hmac_size = s->rtcp_hmac_size = 4;
    } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) {
        // RFC 5764 section 4.1.2
        s->rtp_hmac_size  = 4;
        s->rtcp_hmac_size = 10;
    } else {
        av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
                                     suite);
        return AVERROR(EINVAL);
    }
    if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
        av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
        return AVERROR(EINVAL);
    }
    // MKI and lifetime not handled yet
    s->aes  = av_aes_alloc();
    s->hmac = av_hmac_alloc(AV_HMAC_SHA1);
    if (!s->aes || !s->hmac)
        return AVERROR(ENOMEM);
    memcpy(s->master_key, buf, 16);
    memcpy(s->master_salt, buf + 16, 14);

    // RFC 3711
    av_aes_init(s->aes, s->master_key, 128, 0);

    derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
    derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
    derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));

    derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
    derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
    derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
    return 0;
}
Example #11
0
secure_vector<uint8_t>
pbes2_decrypt(const secure_vector<uint8_t>& key_bits,
              const std::string& passphrase,
              const std::vector<uint8_t>& params)
   {
   AlgorithmIdentifier kdf_algo, enc_algo;

   BER_Decoder(params)
      .start_cons(SEQUENCE)
         .decode(kdf_algo)
         .decode(enc_algo)
      .end_cons();

   const std::string cipher = OIDS::lookup(enc_algo.get_oid());
   const std::vector<std::string> cipher_spec = split_on(cipher, '/');
   if(cipher_spec.size() != 2)
      throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher);
   if(!known_pbes_cipher_mode(cipher_spec[1]))
      throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher);

   secure_vector<uint8_t> iv;
   BER_Decoder(enc_algo.get_parameters()).decode(iv, OCTET_STRING).verify_end();

   std::unique_ptr<Cipher_Mode> dec = Cipher_Mode::create(cipher, DECRYPTION);
   if(!dec)
      throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher);

   dec->set_key(derive_key(passphrase, kdf_algo, dec->key_spec().maximum_keylength()));

   dec->start(iv);

   secure_vector<uint8_t> buf = key_bits;
   dec->finish(buf);

   return buf;
   }
Example #12
0
int
zfs_crypto_load_key(zfs_handle_t *zhp, boolean_t noop, char *alt_keylocation)
{
	int ret, attempts = 0;
	char errbuf[1024];
	uint64_t keystatus, iters = 0, salt = 0;
	uint64_t keyformat = ZFS_KEYFORMAT_NONE;
	char prop_keylocation[MAXNAMELEN];
	char prop_encroot[MAXNAMELEN];
	char *keylocation = NULL;
	uint8_t *key_material = NULL, *key_data = NULL;
	size_t key_material_len;
	boolean_t is_encroot, can_retry = B_FALSE, correctible = B_FALSE;

	(void) snprintf(errbuf, sizeof (errbuf),
	    dgettext(TEXT_DOMAIN, "Key load error"));

	/* check that encryption is enabled for the pool */
	if (!encryption_feature_is_enabled(zhp->zpool_hdl)) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Encryption feature not enabled."));
		ret = EINVAL;
		goto error;
	}

	/* Fetch the keyformat. Check that the dataset is encrypted. */
	keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT);
	if (keyformat == ZFS_KEYFORMAT_NONE) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "'%s' is not encrypted."), zfs_get_name(zhp));
		ret = EINVAL;
		goto error;
	}

	/*
	 * Fetch the key location. Check that we are working with an
	 * encryption root.
	 */
	ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, prop_encroot);
	if (ret != 0) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Failed to get encryption root for '%s'."),
		    zfs_get_name(zhp));
		goto error;
	} else if (!is_encroot) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Keys must be loaded for encryption root of '%s' (%s)."),
		    zfs_get_name(zhp), prop_encroot);
		ret = EINVAL;
		goto error;
	}

	/*
	 * if the caller has elected to override the keylocation property
	 * use that instead
	 */
	if (alt_keylocation != NULL) {
		keylocation = alt_keylocation;
	} else {
		ret = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION, prop_keylocation,
		    sizeof (prop_keylocation), NULL, NULL, 0, B_TRUE);
		if (ret != 0) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Failed to get keylocation for '%s'."),
			    zfs_get_name(zhp));
			goto error;
		}

		keylocation = prop_keylocation;
	}

	/* check that the key is unloaded unless this is a noop */
	if (!noop) {
		keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
		if (keystatus == ZFS_KEYSTATUS_AVAILABLE) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Key already loaded for '%s'."), zfs_get_name(zhp));
			ret = EEXIST;
			goto error;
		}
	}

	/* passphrase formats require a salt and pbkdf2_iters property */
	if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) {
		salt = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_SALT);
		iters = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_ITERS);
	}

try_again:
	/* fetching and deriving the key are correctible errors. set the flag */
	correctible = B_TRUE;

	/* get key material from key format and location */
	ret = get_key_material(zhp->zfs_hdl, B_FALSE, B_FALSE, keyformat,
	    keylocation, zfs_get_name(zhp), &key_material, &key_material_len,
	    &can_retry);
	if (ret != 0)
		goto error;

	/* derive a key from the key material */
	ret = derive_key(zhp->zfs_hdl, keyformat, iters, key_material,
	    key_material_len, salt, &key_data);
	if (ret != 0)
		goto error;

	correctible = B_FALSE;

	/* pass the wrapping key and noop flag to the ioctl */
	ret = lzc_load_key(zhp->zfs_name, noop, key_data, WRAPPING_KEY_LEN);
	if (ret != 0) {
		switch (ret) {
		case EPERM:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Permission denied."));
			break;
		case EINVAL:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Invalid parameters provided for dataset %s."),
			    zfs_get_name(zhp));
			break;
		case EEXIST:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Key already loaded for '%s'."), zfs_get_name(zhp));
			break;
		case EBUSY:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "'%s' is busy."), zfs_get_name(zhp));
			break;
		case EACCES:
			correctible = B_TRUE;
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Incorrect key provided for '%s'."),
			    zfs_get_name(zhp));
			break;
		}
		goto error;
	}

	free(key_material);
	free(key_data);

	return (0);

error:
	zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
	if (key_material != NULL)
		free(key_material);
	if (key_data != NULL)
		free(key_data);

	/*
	 * Here we decide if it is ok to allow the user to retry entering their
	 * key. The can_retry flag will be set if the user is entering their
	 * key from an interactive prompt. The correctible flag will only be
	 * set if an error that occured could be corrected by retrying. Both
	 * flags are needed to allow the user to attempt key entry again
	 */
	if (can_retry && correctible && attempts <= MAX_KEY_PROMPT_ATTEMPTS) {
		attempts++;
		goto try_again;
	}

	return (ret);
}
Example #13
0
status_t
VolumeCryptContext::_Detect(int fd, off_t offset, off_t size, const uint8* key,
	uint32 keyLength, uint8* buffer, true_crypt_header& header)
{
	ssize_t bytesRead = read_pos(fd, offset, buffer, BLOCK_SIZE);
	if (bytesRead != BLOCK_SIZE)
		return bytesRead < 0 ? errno : B_IO_ERROR;

	// decrypt header first

	uint8* encryptedHeader = buffer + PKCS5_SALT_SIZE;
	uint8* salt = buffer;
	uint8 diskKey[DISK_KEY_SIZE];

	derive_key(key, keyLength, salt, PKCS5_SALT_SIZE, diskKey, DISK_KEY_SIZE);
//dprintf("salt %x, key %x\n", *(int*)salt, *(int*)diskKey);

	status_t status = Init(ALGORITHM_AES, MODE_XTS, diskKey, DISK_KEY_SIZE);
	if (status != B_OK)
		return status;

	memcpy(&header, encryptedHeader, sizeof(true_crypt_header));

	Decrypt((uint8*)&header, sizeof(true_crypt_header));

	if (!valid_true_crypt_header(header)) {
		dump_true_crypt_header(header);

		// Try with legacy encryption mode LRW instead
		status = Init(ALGORITHM_AES, MODE_LRW, diskKey, DISK_KEY_SIZE);
		if (status != B_OK)
			return status;

		memcpy(&header, encryptedHeader, sizeof(true_crypt_header));

		Decrypt((uint8*)&header, sizeof(true_crypt_header));

		if (!valid_true_crypt_header(header)) {
			dump_true_crypt_header(header);
			return B_PERMISSION_DENIED;
		}
	}

	if (header.RequiredProgramVersion() >= 0x700) {
		// TODO: test if the block size is really not 512 bytes
		dprintf("header version not yet supported!\n");
		return B_NOT_SUPPORTED;
	}

	// then init context with the keys from the unencrypted header

	SetKey(header.disk_key, sizeof(header.disk_key));

	if (offset != 0) {
		// this is a hidden drive, take over the size from the header
		fSize = B_BENDIAN_TO_HOST_INT64(header.hidden_size);
		fOffset = offset - fSize;
		fHidden = true;
	} else {
		fOffset = BLOCK_SIZE;
		fSize = size - BLOCK_SIZE;
		fHidden = false;
	}
	if (header.Version() >= 4) {
		fOffset = header.EncryptedOffset();
		fSize = header.EncryptedSize();
	}

	fMode->SetBlockOffset(fOffset / BLOCK_SIZE);
	return B_OK;
}
Example #14
0
int nterfacer_line_event(struct esocket *sock, char *newline) {
  struct sconnect *socket = sock->tag;
  char *response, *theirnonceh = NULL, *theirivh = NULL;
  unsigned char theirnonce[16], theiriv[16];
  int number, reason;

  switch(socket->status) {
    case SS_IDLE:
      if(strcasecmp(newline, ANTI_FULL_VERSION)) {
        nterface_log(nrl, NL_INFO, "Protocol mismatch from %s: %s", socket->permit->hostname->content, newline);
        return 1;
      } else {
        unsigned char challenge[32];
        char ivhex[16 * 2 + 1], noncehex[16 * 2 + 1];

        if(!get_entropy(challenge, 32) || !get_entropy(socket->iv, 16)) {
          nterface_log(nrl, NL_ERROR, "Unable to open challenge/IV entropy bin!");
          return 1;
        }

        int_to_hex(challenge, socket->challenge, 32);
        int_to_hex(socket->iv, ivhex, 16);

        memcpy(socket->response, challenge_response(socket->challenge, socket->permit->password->content), sizeof(socket->response));
        socket->response[sizeof(socket->response) - 1] = '\0'; /* just in case */

        socket->status = SS_VERSIONED;
        if(!generate_nonce(socket->ournonce, 1)) {
          nterface_log(nrl, NL_ERROR, "Unable to generate nonce!");
          return 1;
        }
        int_to_hex(socket->ournonce, noncehex, 16);

        if(esocket_write_line(sock, "%s %s %s", socket->challenge, ivhex, noncehex))
           return BUF_ERROR;
        return 0;
      }
      break;
    case SS_VERSIONED:
      for(response=newline;*response;response++) {
        if((*response == ' ') && (*(response + 1))) {
          *response = '\0';
          theirivh = response + 1;
          break;
        }
      }

      if(theirivh) {
        for(response=theirivh;*response;response++) {
          if((*response == ' ') && (*(response + 1))) {
            *response = '\0';
            theirnonceh = response + 1;
            break;
          }
        }
      }

      if(!theirivh || (strlen(theirivh) != 32) || !hex_to_int(theirivh, theiriv, sizeof(theiriv)) ||
         !theirnonceh || (strlen(theirnonceh) != 32) || !hex_to_int(theirnonceh, theirnonce, sizeof(theirnonce))) {
        nterface_log(nrl, NL_INFO, "Protocol error drop: %s", socket->permit->hostname->content);
        return 1;
      }

      if(!memcmp(socket->ournonce, theirnonce, sizeof(theirnonce))) {
        nterface_log(nrl, NL_INFO, "Bad nonce drop: %s", socket->permit->hostname->content);
        return 1;
      }

      if(!strncasecmp(newline, socket->response, sizeof(socket->response))) {
        unsigned char theirkey[32], ourkey[32];

        derive_key(ourkey, socket->permit->password->content, socket->challenge, socket->ournonce, theirnonce, (unsigned char *)"SERVER", 6);

        derive_key(theirkey, socket->permit->password->content, socket->response, theirnonce, socket->ournonce, (unsigned char *)"CLIENT", 6);
        nterface_log(nrl, NL_INFO, "Authed: %s", socket->permit->hostname->content);
        socket->status = SS_AUTHENTICATED;
        switch_buffer_mode(sock, ourkey, socket->iv, theirkey, theiriv);

        if(esocket_write_line(sock, "Oauth"))
          return BUF_ERROR;
      } else {
        nterface_log(nrl, NL_INFO, "Bad CR drop: %s", socket->permit->hostname->content);
        
        return 1;
      }
      break;
    case SS_AUTHENTICATED:
      nterface_log(nrl, NL_INFO|NL_LOG_ONLY, "L(%s): %s", socket->permit->hostname->content, newline);
      reason = nterfacer_new_rline(newline, sock, &number);
      if(reason) {
        if(reason == RE_SOCKET_ERROR)
          return BUF_ERROR;
        if(reason != RE_BAD_LINE) {
          if(esocket_write_line(sock, "%d,E%d,%s", number, reason, request_error(reason)))
            return BUF_ERROR;
          return 0;
        } else {
          return 1;
        }
      }
      break;
  }

  return 0;
}
Example #15
0
Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
                                         const std::string& passphrase,
                                         RandomNumberGenerator& rng,
                                         size_t max_sessions,
                                         std::chrono::seconds session_lifetime) :
   m_db(db),
   m_rng(rng),
   m_max_sessions(max_sessions),
   m_session_lifetime(session_lifetime)
   {
   m_db->create_table(
      "create table if not exists tls_sessions "
      "("
      "session_id TEXT PRIMARY KEY, "
      "session_start INTEGER, "
      "hostname TEXT, "
      "hostport INTEGER, "
      "session BLOB"
      ")");

   m_db->create_table(
      "create table if not exists tls_sessions_metadata "
      "("
      "passphrase_salt BLOB, "
      "passphrase_iterations INTEGER, "
      "passphrase_check INTEGER "
      ")");

   const size_t salts = m_db->row_count("tls_sessions_metadata");

   if(salts == 1)
      {
      // existing db
      auto stmt = m_db->new_statement("select * from tls_sessions_metadata");

      if(stmt->step())
         {
         std::pair<const byte*, size_t> salt = stmt->get_blob(0);
         const size_t iterations = stmt->get_size_t(1);
         const size_t check_val_db = stmt->get_size_t(2);

         size_t check_val_created;
         m_session_key = derive_key(passphrase,
                                    salt.first,
                                    salt.second,
                                    iterations,
                                    check_val_created);

         if(check_val_created != check_val_db)
            throw std::runtime_error("Session database password not valid");
         }
      }
   else
      {
      // maybe just zap the salts + sessions tables in this case?
      if(salts != 0)
         throw std::runtime_error("Seemingly corrupted database, multiple salts found");

      // new database case

      std::vector<byte> salt = unlock(rng.random_vec(16));
      const size_t iterations = 256 * 1024;
      size_t check_val = 0;

      m_session_key = derive_key(passphrase, salt.data(), salt.size(),
                                 iterations, check_val);

      auto stmt = m_db->new_statement("insert into tls_sessions_metadata values(?1, ?2, ?3)");

      stmt->bind(1, salt);
      stmt->bind(2, iterations);
      stmt->bind(3, check_val);

      stmt->spin();
      }
   }
Example #16
0
/*************************************************
* Derive a key                                   *
*************************************************/
SecureVector<byte> DH_PrivateKey::derive_key(const byte w[],
                                             u32bit w_len) const
   {
   return derive_key(BigInt::decode(w, w_len));
   }
Example #17
0
// Verify message 1 then generate and return message 2 to isv.
int sp_ra_proc_msg1_req(const sample_ra_msg1_t *p_msg1,
						uint32_t msg1_size,
						ra_samp_response_header_t **pp_msg2)
{
    int ret = 0;
    ra_samp_response_header_t* p_msg2_full = NULL;
    sample_ra_msg2_t *p_msg2 = NULL;
    sample_ecc_state_handle_t ecc_state = NULL;
    sample_status_t sample_ret = SAMPLE_SUCCESS;
    bool derive_ret = false;

    if(!p_msg1 ||
       !pp_msg2 ||
       (msg1_size != sizeof(sample_ra_msg1_t)))
    {
        return -1;
    }

    // Check to see if we have registered?
    if (!g_is_sp_registered)
    {
        return SP_UNSUPPORTED_EXTENDED_EPID_GROUP;
    }

    do
    {
        // Get the sig_rl from attestation server using GID.
        // GID is Base-16 encoded of EPID GID in little-endian format.
        // In the product, the SP and attesation server uses an established channel for
        // communication.
        uint8_t* sig_rl;
        uint32_t sig_rl_size = 0;

        // The product interface uses a REST based message to get the SigRL.
        
        ret = g_sp_extended_epid_group_id->get_sigrl(p_msg1->gid, &sig_rl_size, &sig_rl);
        if(0 != ret)
        {
            fprintf(stderr, "\nError, ias_get_sigrl [%s].", __FUNCTION__);
            ret = SP_IAS_FAILED;
            break;
        }

        // Need to save the client's public ECCDH key to local storage
        if (memcpy_s(&g_sp_db.g_a, sizeof(g_sp_db.g_a), &p_msg1->g_a,
                     sizeof(p_msg1->g_a)))
        {
            fprintf(stderr, "\nError, cannot do memcpy in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // Generate the Service providers ECCDH key pair.
        sample_ret = sample_ecc256_open_context(&ecc_state);
        if(SAMPLE_SUCCESS != sample_ret)
        {
            fprintf(stderr, "\nError, cannot get ECC context in [%s].",
                             __FUNCTION__);
            ret = -1;
            break;
        }
        sample_ec256_public_t pub_key = {{0},{0}};
        sample_ec256_private_t priv_key = {{0}};
        sample_ret = sample_ecc256_create_key_pair(&priv_key, &pub_key,
                                                   ecc_state);
        if(SAMPLE_SUCCESS != sample_ret)
        {
            fprintf(stderr, "\nError, cannot generate key pair in [%s].",
                    __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // Need to save the SP ECCDH key pair to local storage.
        if(memcpy_s(&g_sp_db.b, sizeof(g_sp_db.b), &priv_key,sizeof(priv_key))
           || memcpy_s(&g_sp_db.g_b, sizeof(g_sp_db.g_b),
                       &pub_key,sizeof(pub_key)))
        {
            fprintf(stderr, "\nError, cannot do memcpy in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // Generate the client/SP shared secret
        sample_ec_dh_shared_t dh_key = {{0}};
        sample_ret = sample_ecc256_compute_shared_dhkey(&priv_key,
            (sample_ec256_public_t *)&p_msg1->g_a,
            (sample_ec256_dh_shared_t *)&dh_key,
            ecc_state);
        if(SAMPLE_SUCCESS != sample_ret)
        {
            fprintf(stderr, "\nError, compute share key fail in [%s].",
                    __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

#ifdef SUPPLIED_KEY_DERIVATION

        // smk is only needed for msg2 generation.
        derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SMK_SK,
            &g_sp_db.smk_key, &g_sp_db.sk_key);
        if(derive_ret != true)
        {
            fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // The rest of the keys are the shared secrets for future communication.
        derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_MK_VK,
            &g_sp_db.mk_key, &g_sp_db.vk_key);
        if(derive_ret != true)
        {
            fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }
#else
        // smk is only needed for msg2 generation.
        derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SMK,
                                &g_sp_db.smk_key);
        if(derive_ret != true)
        {
            fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // The rest of the keys are the shared secrets for future communication.
        derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_MK,
                                &g_sp_db.mk_key);
        if(derive_ret != true)
        {
            fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_SK,
                                &g_sp_db.sk_key);
        if(derive_ret != true)
        {
            fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        derive_ret = derive_key(&dh_key, SAMPLE_DERIVE_KEY_VK,
                                &g_sp_db.vk_key);
        if(derive_ret != true)
        {
            fprintf(stderr, "\nError, derive key fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }
#endif

        uint32_t msg2_size = sizeof(sample_ra_msg2_t) + sig_rl_size;
        p_msg2_full = (ra_samp_response_header_t*)malloc(msg2_size
                      + sizeof(ra_samp_response_header_t));
        if(!p_msg2_full)
        {
            fprintf(stderr, "\nError, out of memory in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }
        memset(p_msg2_full, 0, msg2_size + sizeof(ra_samp_response_header_t));
        p_msg2_full->type = TYPE_RA_MSG2;
        p_msg2_full->size = msg2_size;
        // The simulated message2 always passes.  This would need to be set
        // accordingly in a real service provider implementation.
        p_msg2_full->status[0] = 0;
        p_msg2_full->status[1] = 0;
        p_msg2 = (sample_ra_msg2_t *)p_msg2_full->body;

        // Assemble MSG2
        if(memcpy_s(&p_msg2->g_b, sizeof(p_msg2->g_b), &g_sp_db.g_b,
                    sizeof(g_sp_db.g_b)) ||
           memcpy_s(&p_msg2->spid, sizeof(sample_spid_t),
                    &g_spid, sizeof(g_spid)))
        {
            fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // The service provider is responsible for selecting the proper EPID
        // signature type and to understand the implications of the choice!
        p_msg2->quote_type = SAMPLE_QUOTE_LINKABLE_SIGNATURE;

#ifdef SUPPLIED_KEY_DERIVATION
//isv defined key derivation function id
#define ISV_KDF_ID 2
        p_msg2->kdf_id = ISV_KDF_ID;
#else
        p_msg2->kdf_id = SAMPLE_AES_CMAC_KDF_ID;
#endif
        // Create gb_ga
        sample_ec_pub_t gb_ga[2];
        if(memcpy_s(&gb_ga[0], sizeof(gb_ga[0]), &g_sp_db.g_b,
                    sizeof(g_sp_db.g_b))
           || memcpy_s(&gb_ga[1], sizeof(gb_ga[1]), &g_sp_db.g_a,
                       sizeof(g_sp_db.g_a)))
        {
            fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // Sign gb_ga
        sample_ret = sample_ecdsa_sign((uint8_t *)&gb_ga, sizeof(gb_ga),
                        (sample_ec256_private_t *)&g_sp_priv_key,
                        (sample_ec256_signature_t *)&p_msg2->sign_gb_ga,
                        ecc_state);
        if(SAMPLE_SUCCESS != sample_ret)
        {
            fprintf(stderr, "\nError, sign ga_gb fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        // Generate the CMACsmk for gb||SPID||TYPE||KDF_ID||Sigsp(gb,ga)
        uint8_t mac[SAMPLE_EC_MAC_SIZE] = {0};
        uint32_t cmac_size = offsetof(sample_ra_msg2_t, mac);
        sample_ret = sample_rijndael128_cmac_msg(&g_sp_db.smk_key,
            (uint8_t *)&p_msg2->g_b, cmac_size, &mac);
        if(SAMPLE_SUCCESS != sample_ret)
        {
            fprintf(stderr, "\nError, cmac fail in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }
        if(memcpy_s(&p_msg2->mac, sizeof(p_msg2->mac), mac, sizeof(mac)))
        {
            fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }

        if(memcpy_s(&p_msg2->sig_rl[0], sig_rl_size, sig_rl, sig_rl_size))
        {
            fprintf(stderr,"\nError, memcpy failed in [%s].", __FUNCTION__);
            ret = SP_INTERNAL_ERROR;
            break;
        }
        p_msg2->sig_rl_size = sig_rl_size;

    }while(0);

    if(ret)
    {
        *pp_msg2 = NULL;
        SAFE_FREE(p_msg2_full);
    }
    else
    {
        // Freed by the network simulator in ra_free_network_response_buffer
        *pp_msg2 = p_msg2_full;
    }

    if(ecc_state)
    {
        sample_ecc256_close_context(ecc_state);
    }

    return ret;
}
Example #18
0
/*************************************************
* Derive a key                                   *
*************************************************/
SecureVector<byte> DH_PrivateKey::derive_key(const DH_PublicKey& key) const
   {
   return derive_key(key.get_y());
   }
Example #19
0
static int
populate_create_encryption_params_nvlists(libzfs_handle_t *hdl,
    zfs_handle_t *zhp, boolean_t newkey, zfs_keyformat_t keyformat,
    char *keylocation, nvlist_t *props, uint8_t **wkeydata, uint_t *wkeylen)
{
	int ret;
	uint64_t iters = 0, salt = 0;
	uint8_t *key_material = NULL;
	size_t key_material_len = 0;
	uint8_t *key_data = NULL;
	const char *fsname = (zhp) ? zfs_get_name(zhp) : NULL;

	/* get key material from keyformat and keylocation */
	ret = get_key_material(hdl, B_TRUE, newkey, keyformat, keylocation,
	    fsname, &key_material, &key_material_len, NULL);
	if (ret != 0)
		goto error;

	/* passphrase formats require a salt and pbkdf2 iters property */
	if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) {
		/* always generate a new salt */
		random_init();
		ret = random_get_bytes((uint8_t *)&salt, sizeof (uint64_t));
		if (ret != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Failed to generate salt."));
			goto error;
		}
		random_fini();

		ret = nvlist_add_uint64(props,
		    zfs_prop_to_name(ZFS_PROP_PBKDF2_SALT), salt);
		if (ret != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				"Failed to add salt to properties."));
			goto error;
		}

		/*
		 * If not otherwise specified, use the default number of
		 * pbkdf2 iterations. If specified, we have already checked
		 * that the given value is greater than MIN_PBKDF2_ITERATIONS
		 * during zfs_valid_proplist().
		 */
		ret = nvlist_lookup_uint64(props,
		    zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters);
		if (ret == ENOENT) {
			iters = DEFAULT_PBKDF2_ITERATIONS;
			ret = nvlist_add_uint64(props,
			    zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), iters);
			if (ret != 0)
				goto error;
		} else if (ret != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Failed to get pbkdf2 iterations."));
			goto error;
		}
	} else {
		/* check that pbkdf2iters was not specified by the user */
		ret = nvlist_lookup_uint64(props,
		    zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters);
		if (ret == 0) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Cannot specify pbkdf2iters with a non-passphrase "
			    "keyformat."));
			goto error;
		}
	}

	/* derive a key from the key material */
	ret = derive_key(hdl, keyformat, iters, key_material, key_material_len,
	    salt, &key_data);
	if (ret != 0)
		goto error;

	free(key_material);

	*wkeydata = key_data;
	*wkeylen = WRAPPING_KEY_LEN;
	return (0);

error:
	if (key_material != NULL)
		free(key_material);
	if (key_data != NULL)
		free(key_data);

	*wkeydata = NULL;
	*wkeylen = 0;
	return (ret);
}
Example #20
0
// Saves file with specified index and closes file descriptor (if force is 1,
// attempts to save data even if file is not yet complete). Returns 0 on
// success and -1 on error.
int Saverestoredfile(int slot,int force) {
  int n,success;
  ushort filecrc;
  ulong l,length;
  uchar *bufout,*data,*tempdata,*salt,key[AESKEYLEN],iv[16];
  t_fproc *pf;
  aes_decrypt_ctx ctx[1];
  HANDLE hfile;
  if (slot<0 || slot>=NFILE)
    return -1;                         // Invalid index of file descriptor
  pf=fproc+slot;
  if (pf->busy==0 || pf->nblock==0)
    return -1;                         // Index points to unused descriptor
  if (pf->ndata!=pf->nblock && force==0)
    return -1;                         // Still incomplete data
  Message("",0);
  // If data is encrypted, decrypt it to temporary buffer. Decryption in place
  // is possible, but the whole data would be lost if password is incorrect.
  if (pf->mode & PBM_ENCRYPTED) {
    if (pf->datasize & 0x0000000F) {
      Reporterror("Encrypted data is not aligned");
      return -1; };
    if (Getpassword()!=0)
      return -1;                       // User cancelled decryption
    tempdata=(uchar *)GlobalAlloc(GMEM_FIXED,pf->datasize);
    if (tempdata==NULL) {
      Reporterror("Low memory, can't decrypt data");
      return -1; };
    n=strlen(password);
    salt=(uchar *)(pf->name)+32; // hack: put the salt & iv at the end of the name field
    derive_key((const uchar *)password, n, salt, 16, 524288, key, AESKEYLEN);
    memset(password,0,sizeof(password));
    memset(ctx,0,sizeof(aes_decrypt_ctx));
    if(aes_decrypt_key((const uchar *)key,AESKEYLEN,ctx) == EXIT_FAILURE) {
      memset(key,0,AESKEYLEN);
      Reporterror("Failed to set decryption key");
      return -1; };
    memset(key,0,AESKEYLEN);
    memcpy(iv, salt+16, 16); // the second 16-byte block in 'salt' is the IV
    if(aes_cbc_decrypt(pf->data,tempdata,pf->datasize,iv,ctx) == EXIT_FAILURE) {
      Reporterror("Failed to decrypt data");
      memset(ctx,0,sizeof(aes_decrypt_ctx));
      return -1; };
    memset(ctx,0,sizeof(aes_decrypt_ctx));
    filecrc=Crc16(tempdata,pf->datasize);
    if (filecrc!=(ushort)pf->filecrc) {
      Reporterror("Invalid password, please try again");
      GlobalFree((HGLOBAL)tempdata);
      return -1; }
    else {
      GlobalFree((HGLOBAL)pf->data);
      pf->data=tempdata;
      pf->mode&=~PBM_ENCRYPTED;
    };
  };
  // If data is compressed, unpack it to temporary buffer.
  if ((pf->mode & PBM_COMPRESSED)==0) {
    // Data is not compressed.
    data=pf->data; length=pf->origsize;
    bufout=NULL; }
  else {
    // Data is compressed. Create temporary buffer.
    if (pf->origsize==0)
      pf->origsize=pf->datasize*4;     // Weak attempt to recover
    bufout=(uchar *)GlobalAlloc(GMEM_FIXED,pf->origsize);
    if (bufout==NULL) {
      Reporterror("Low memory");
      return -1; };
    // Unpack data.
    length=pf->origsize;
    success=BZ2_bzBuffToBuffDecompress((char *)bufout,(uint *)&length,
      (char *)pf->data,pf->datasize,0,0);
    if (success!=BZ_OK) {
      GlobalFree((HGLOBAL)bufout);
      Reporterror("Unable to unpack data");
      return -1; };
    data=bufout; };
  // Ask user for file name.
  if (Selectoutfile(pf->name)!=0) {    // Cancelled by user
    if (bufout!=NULL) GlobalFree((HGLOBAL)bufout);
    return -1; };
  // Open file and save data.
  hfile=CreateFile(outfile,GENERIC_WRITE,0,NULL,
    CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  if (hfile==INVALID_HANDLE_VALUE) {
    if (bufout!=NULL) GlobalFree((HGLOBAL)bufout);
    Reporterror("Unable to create file");
    return -1; };
  WriteFile(hfile,data,length,&l,NULL);
  // Restore old modification date and time.
  SetFileTime(hfile,&pf->modified,&pf->modified,&pf->modified);
  // Close file and restore old basic attributes.
  CloseHandle(hfile);
  SetFileAttributes(outfile,pf->attributes);
  if (bufout!=NULL) GlobalFree((HGLOBAL)bufout);
  if (l!=length) {
    Reporterror("I/O error");
    return -1; };
  // Close file descriptor and report success.
  Closefproc(slot);
  Message("File saved",0);
  return 0;
};
Example #21
0
/*
 * Save all files in rootdir to a container
 */
int memfile_savefiles(char * filename, char * password, memfile * root)
{
    FILE *  f ;
    int     i ;

    uint8_t nonce[NONCE_SZ];
    uint8_t key[KEY_SZ];
    uint8_t canari[CANARI_SZ];
    char    enc_name[MAXNAMESZ];
    uint64_t    u1, u2, u3 ;

    size_t  offset=0 ;

    /* Generate nonce */
    memcpy(nonce, get_nonce(), NONCE_SZ);
    /* Derive key from password */
    derive_key(password,
               strlen(password),
               nonce,
               NONCE_SZ,
               key,
               KEY_SZ,
               20000);
    /*
     * A container header is composed of:
     * A magic number of MAGIC_SZ bytes
     * A version number on 2 bytes: major.minor
     * A nonce of size NONCE_SZ bytes
     * A canari of size CANARI_SZ bytes
     */
    if ((f=fopen(filename, "w"))==NULL) {
        return 0 ;
    }
    /* Write magic number */
    fwrite(mefs_magic, 1, MAGIC_SZ, f);
    /* Write version */
    fwrite(mefs_version, 1, 2, f);
    /* Write nonce */
    fwrite(nonce, 1, NONCE_SZ, f);
    /* Generate and encrypt canari */
    for (i=0 ; i<CANARI_SZ ; i++) {
        canari[i] = 0xaa ;
    }
    stream_cipher(canari, CANARI_SZ, 0, key, nonce);
    fwrite(canari, 1, CANARI_SZ, f);
    offset += CANARI_SZ ;

    /* Write files one by one */
    /*
     * filename is a zero-padded string of size MAXNAMESZ
     * filesize on a 64 big-endian unsigned int
     * ctime    on a 64-big-endian unsigned int
     * mtime    on a 64-big-endian unsigned int
     */
    for (i=0 ; i<MAXFILES ; i++) {
        if (root[i].name==NULL) {
            continue ;
        }
        memset(enc_name, 0, MAXNAMESZ);
        strncpy(enc_name, root[i].name, MAXNAMESZ);
        stream_cipher(enc_name, MAXNAMESZ, offset, key, nonce);
        offset += MAXNAMESZ ;
        fwrite(enc_name, 1, MAXNAMESZ,  f);

        u1 = root[i].sta.st_size ;
        u2 = root[i].sta.st_ctime ;
        u3 = root[i].sta.st_mtime ;

        stream_cipher((uint8_t*)&u1, sizeof(uint64_t), offset, key, nonce);
        offset += sizeof(uint64_t);
        fwrite(&u1, sizeof(uint64_t), 1, f);

        stream_cipher((uint8_t*)&u2, sizeof(uint64_t), offset, key, nonce);
        offset += sizeof(uint64_t);
        fwrite(&u2, sizeof(uint64_t), 1, f);

        stream_cipher((uint8_t*)&u3, sizeof(uint64_t), offset, key, nonce);
        offset += sizeof(uint64_t);
        fwrite(&u3, sizeof(uint64_t), 1, f);

        stream_cipher(root[i].data,
                      root[i].sta.st_size, 
                      offset,
                      key,
                      nonce);
        offset += root[i].sta.st_size ;
        fwrite(root[i].data, 1, root[i].sta.st_size, f);
    }
    fclose(f);
    return 0 ;
}
Example #22
0
/*
 * Read a container with the provided key
 * Read all files and place them into the provided list
 * Returns:
 * >0   Number of read files
 * -1   File error during reading
 * -2   Wrong password in input
 */
int memfile_readfiles(char * filename, char * password, memfile * root)
{
    char *  buf ;
    char *  cur ;
    int     fd ;
    int     i ;
    struct stat fileinfo ;

    uint8_t nonce[NONCE_SZ];
    uint8_t key[KEY_SZ];

    uint64_t    u1, u2, u3 ;
    size_t      header_sz ;
    size_t      payload_sz ;
    char        fname[MAXNAMESZ];

    header_sz = MAGIC_SZ + 2 + NONCE_SZ + CANARI_SZ ;
    /* Find out file size in bytes */
    if (stat(filename, &fileinfo)!=0) {
        logger("no such file: %s", filename);
        return 1 ;
    }
    if (fileinfo.st_size < header_sz) {
        logger("not a container: ", filename);
        return -1 ;
    }
    /* Map input file */
    if ((fd=open(filename, O_RDONLY))==-1) {
        logger("cannot open: %s", filename);
        return -1 ;
    }
    buf = (char*)mmap(0,
                      fileinfo.st_size,
                      PROT_READ | PROT_WRITE,
                      MAP_PRIVATE,
                      fd,
                      0);
    close(fd);
    if (buf==(char*)-1) {
        logger("cannot map: %s", filename);
        return -1;
    }
    cur = buf ;
    payload_sz = fileinfo.st_size - header_sz ;
    /*
     * A container header is composed of:
     * A magic number of MAGIC_SZ bytes
     * A version number on 2 bytes: major.minor
     * A nonce of size NONCE_SZ bytes
     * A canari of size CANARI_SZ bytes
     */
    /* Check magic number */
    for (i=0 ; i<MAGIC_SZ ; i++) {
        if (cur[i]!=mefs_magic[i]) {
            logger("not a container: ", filename);
            munmap(buf, fileinfo.st_size);
            return -1 ;
        }
    }
    cur += MAGIC_SZ ;
    /* Read version number */
    if (cur[0]!=mefs_version[0] ||
        cur[1]!=mefs_version[1]) {
        logger("unsupported version for: ", filename);
        munmap(buf, fileinfo.st_size);
        return -1 ;
    }
    cur+=2 ;

    /* Copy nonce for later use */
    memcpy(nonce, cur, NONCE_SZ);
    cur += NONCE_SZ ;
    /* Derive key from password */
    derive_key(password,
               strlen(password),
               nonce,
               NONCE_SZ,
               key,
               KEY_SZ,
               20000);
    /* Decrypt everything starting from CANARI, using nonce and key */
    stream_cipher(cur,
                  fileinfo.st_size-(MAGIC_SZ+2+NONCE_SZ),
                  0,
                  key,
                  nonce);
    /* Test canari has expected pattern: 0xaaaa...aa */
    for (i=0 ; i<CANARI_SZ ; i++) {
        if ((unsigned char)cur[i]!=0xaa) {
            logger("wrong password for container: %s", filename);
            munmap(buf, fileinfo.st_size);
            return -2 ;
        }
    }
    cur+=CANARI_SZ ;

    /* Read files one by one */
    /*
     * filename is a zero-padded string of size MAXNAMESZ
     * filesize on a 64 big-endian unsigned int
     * ctime    on a 64-big-endian unsigned int
     * mtime    on a 64-big-endian unsigned int
     */
    i=0 ;
    while (1) {
        memcpy(fname, cur, MAXNAMESZ);
        cur+=MAXNAMESZ;
        memcpy(&u1, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);
        memcpy(&u2, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);
        memcpy(&u3, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);

        root[i].name = strdup(fname);
        root[i].sta.st_ino = inode_next();
        root[i].sta.st_size     = u1 ;
        root[i].sta.st_ctime    = u2 ;
        root[i].sta.st_mtime    = u3 ;

        root[i].data = malloc(u1);
        memcpy(root[i].data, cur, u1);
        cur+=u1 ;
        if ((cur-buf) >= fileinfo.st_size)
            break ;
        i++ ;
    }
    munmap(buf, fileinfo.st_size);
    return 0 ;
}
Example #23
0
extern "C" sgx_status_t sgx_ra_proc_msg2_trusted(
    sgx_ra_context_t context,
    const sgx_ra_msg2_t *p_msg2,            //(g_b||spid||quote_type|| KDF_ID ||sign_gb_ga||cmac||sig_rl_size||sig_rl)
    const sgx_target_info_t *p_qe_target,
    sgx_report_t *p_report,
    sgx_quote_nonce_t* p_nonce)
{
    sgx_status_t se_ret = SGX_ERROR_UNEXPECTED;
    //p_msg2[in] p_qe_target[in] p_report[out] p_nonce[out] in EDL file
    if(vector_size(&g_ra_db) <= context
       || !p_msg2
       || !p_qe_target
       || !p_report
       || !p_nonce)
        return SGX_ERROR_INVALID_PARAMETER;

    ra_db_item_t* item = NULL;
    if(0 != vector_get(&g_ra_db, context, reinterpret_cast<void**>(&item)) || item == NULL )
        return SGX_ERROR_INVALID_PARAMETER;

    sgx_ec256_private_t a;
    memset(&a, 0, sizeof(a));
    // Create gb_ga
    sgx_ec256_public_t gb_ga[2];
    sgx_ec256_public_t sp_pubkey;
    sgx_ec_key_128bit_t smkey = {0};
    sgx_ec_key_128bit_t skey = {0};
    sgx_ec_key_128bit_t mkey = {0};
    sgx_ec_key_128bit_t vkey = {0};
    sgx_ra_derive_secret_keys_t ra_key_cb = NULL;

    memset(&gb_ga[0], 0, sizeof(gb_ga));
    sgx_spin_lock(&item->item_lock);
    //sgx_ra_get_ga must have been called
    if (item->state != ra_get_gaed)
    {
        sgx_spin_unlock(&item->item_lock);
        return SGX_ERROR_INVALID_STATE;
    }
    memcpy(&a, &item->a, sizeof(a));
    memcpy(&gb_ga[1], &item->g_a, sizeof(gb_ga[1]));
    memcpy(&sp_pubkey, &item->sp_pubkey, sizeof(sp_pubkey));
    ra_key_cb = DEC_KDF_POINTER(item->derive_key_cb);
    sgx_spin_unlock(&item->item_lock);
    memcpy(&gb_ga[0], &p_msg2->g_b, sizeof(gb_ga[0]));

    sgx_ecc_state_handle_t ecc_state = NULL;

    // ecc_state need to be freed when exit.
    se_ret = sgx_ecc256_open_context(&ecc_state);
    if (SGX_SUCCESS != se_ret)
    {
        if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
            se_ret = SGX_ERROR_UNEXPECTED;
        return se_ret;
    }

    sgx_ec256_dh_shared_t dh_key;
    memset(&dh_key, 0, sizeof(dh_key));
    sgx_ec256_public_t* p_msg2_g_b = const_cast<sgx_ec256_public_t*>(&p_msg2->g_b);
    se_ret = sgx_ecc256_compute_shared_dhkey(&a,
        (sgx_ec256_public_t*)p_msg2_g_b,
        &dh_key, ecc_state);
    if(SGX_SUCCESS != se_ret)
    {
        if (SGX_ERROR_OUT_OF_MEMORY != se_ret)
            se_ret = SGX_ERROR_UNEXPECTED;
        sgx_ecc256_close_context(ecc_state);
        return se_ret;
    }
    // Verify signature of gb_ga
    uint8_t result;
    sgx_ec256_signature_t* p_msg2_sign_gb_ga = const_cast<sgx_ec256_signature_t*>(&p_msg2->sign_gb_ga);
    se_ret = sgx_ecdsa_verify((uint8_t *)&gb_ga, sizeof(gb_ga),
        &sp_pubkey,
        p_msg2_sign_gb_ga,
        &result, ecc_state);
    if(SGX_SUCCESS != se_ret)
    {
        if (SGX_ERROR_OUT_OF_MEMORY != se_ret)
            se_ret = SGX_ERROR_UNEXPECTED;
        sgx_ecc256_close_context(ecc_state);
        return se_ret;
    }
    if(SGX_EC_VALID != result)
    {
        sgx_ecc256_close_context(ecc_state);
        return SGX_ERROR_INVALID_SIGNATURE;
    }

    do
    {
        if(NULL != ra_key_cb)
        {
            se_ret = ra_key_cb(&dh_key,
                               p_msg2->kdf_id,
                               &smkey,
                               &skey,
                               &mkey,
                               &vkey);
            if (SGX_SUCCESS != se_ret)
            {
                if(SGX_ERROR_OUT_OF_MEMORY != se_ret &&
                    SGX_ERROR_INVALID_PARAMETER != se_ret &&
                    SGX_ERROR_KDF_MISMATCH != se_ret)
                    se_ret = SGX_ERROR_UNEXPECTED;
                break;
            }
        }
        else if (p_msg2->kdf_id == 0x0001)
        {
            se_ret = derive_key(&dh_key, "SMK", (uint32_t)(sizeof("SMK") -1), &smkey);
            if (SGX_SUCCESS != se_ret)
            {
                if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
                    se_ret = SGX_ERROR_UNEXPECTED;
                break;
            }
            se_ret = derive_key(&dh_key, "SK", (uint32_t)(sizeof("SK") -1), &skey);
            if (SGX_SUCCESS != se_ret)
            {
                if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
                    se_ret = SGX_ERROR_UNEXPECTED;
                break;
            }

            se_ret = derive_key(&dh_key, "MK", (uint32_t)(sizeof("MK") -1), &mkey);
            if (SGX_SUCCESS != se_ret)
            {
                if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
                    se_ret = SGX_ERROR_UNEXPECTED;
                break;
            }

            se_ret = derive_key(&dh_key, "VK", (uint32_t)(sizeof("VK") -1), &vkey);
            if (SGX_SUCCESS != se_ret)
            {
                if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
                    se_ret = SGX_ERROR_UNEXPECTED;
                break;
            }
        }
        else
        {
            se_ret = SGX_ERROR_KDF_MISMATCH;
            break;
        }

        sgx_cmac_128bit_tag_t mac;
        uint32_t maced_size = offsetof(sgx_ra_msg2_t, mac);

        se_ret = sgx_rijndael128_cmac_msg(&smkey, (const uint8_t *)p_msg2, maced_size, &mac);
        if (SGX_SUCCESS != se_ret)
        {
            if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
                se_ret = SGX_ERROR_UNEXPECTED;
            break;
        }
        //Check mac
        if(0 == consttime_memequal(mac, p_msg2->mac, sizeof(mac)))
        {
            se_ret = SGX_ERROR_MAC_MISMATCH;
            break;
        }

        //create a nonce
        se_ret =sgx_read_rand((uint8_t*)p_nonce, sizeof(sgx_quote_nonce_t));
        if (SGX_SUCCESS != se_ret)
        {
            if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
                se_ret = SGX_ERROR_UNEXPECTED;
            break;
        }

        sgx_spin_lock(&item->item_lock);
        //sgx_ra_get_ga must have been called
        if (item->state != ra_get_gaed)
        {
            se_ret = SGX_ERROR_INVALID_STATE;
            sgx_spin_unlock(&item->item_lock);
            break;
        }
        memcpy(&item->g_b, &p_msg2->g_b, sizeof(item->g_b));
        memcpy(&item->smk_key, smkey, sizeof(item->smk_key));
        memcpy(&item->sk_key, skey, sizeof(item->sk_key));
        memcpy(&item->mk_key, mkey, sizeof(item->mk_key));
        memcpy(&item->vk_key, vkey, sizeof(item->vk_key));
        memcpy(&item->qe_target, p_qe_target, sizeof(sgx_target_info_t));
        memcpy(&item->quote_nonce, p_nonce, sizeof(sgx_quote_nonce_t));
        sgx_report_data_t report_data = {{0}};
        se_static_assert(sizeof(sgx_report_data_t)>=sizeof(sgx_sha256_hash_t));
        // H = SHA256(ga || gb || VK_CMAC)
        uint32_t sha256ed_size = offsetof(ra_db_item_t, sp_pubkey);
        //report_data is 512bits, H is 256bits. The H is in the lower 256 bits of report data while the higher 256 bits are all zeros.
        se_ret = sgx_sha256_msg((uint8_t *)&item->g_a, sha256ed_size,
                                (sgx_sha256_hash_t *)&report_data);
        if(SGX_SUCCESS != se_ret)
        {
            if (SGX_ERROR_OUT_OF_MEMORY != se_ret)
                se_ret = SGX_ERROR_UNEXPECTED;
            sgx_spin_unlock(&item->item_lock);
            break;
        }
        //REPORTDATA = H
        se_ret = sgx_create_report(p_qe_target, &report_data, p_report);
        if (SGX_SUCCESS != se_ret)
        {
            if(SGX_ERROR_OUT_OF_MEMORY != se_ret)
                se_ret = SGX_ERROR_UNEXPECTED;
            sgx_spin_unlock(&item->item_lock);
            break;
        }
        item->state = ra_proc_msg2ed;
        sgx_spin_unlock(&item->item_lock);
    }while(0);
    memset_s(&dh_key, sizeof(dh_key), 0, sizeof(dh_key));
    sgx_ecc256_close_context(ecc_state);
    memset_s(&a, sizeof(sgx_ec256_private_t),0, sizeof(sgx_ec256_private_t));
    memset_s(smkey, sizeof(sgx_ec_key_128bit_t),0, sizeof(sgx_ec_key_128bit_t));
    memset_s(skey, sizeof(sgx_ec_key_128bit_t),0, sizeof(sgx_ec_key_128bit_t));
    memset_s(mkey, sizeof(sgx_ec_key_128bit_t),0, sizeof(sgx_ec_key_128bit_t));
    memset_s(vkey, sizeof(sgx_ec_key_128bit_t),0, sizeof(sgx_ec_key_128bit_t));
    return se_ret;
}
int
main (int argc, char **argv)
{
  const char *ke_msg1 = NULL;
  char *ke_msg2 = NULL;
  char *ca_file = NULL;
  char *sk_file = NULL;
  char *cert_file = NULL;
  char *resp_id = NULL;
  int out_fd;
  flow1 *to_b = NULL;
  flow2 *from_b = NULL;
  cert *own_cert = NULL;
  dckey *sk = NULL;
  dckey *ca_pk = NULL;
  u_char seskey[sha1_hashsize], secret[aes_blocklen];
  char *pretty_secret = NULL;

  if ((argc == 5) && argv[1][0] != '-') {
    /* no -p option */
    ca_file = "./.pki/ca.pub";
  }
  else if ((argc == 6)
	   && (argv[1][0] != '-') 
	   && (argv[1] + 1) && (argv[1][1] != 'p')
	   && (argv[1] + 2)) {
    /* -p option present, followed by CERT-FILE without separating blank  */
    ca_file = argv[1] + 2;
  }
  else if ((argc == 7) && !strcmp (argv[1], "-p")) {
    /* -p option present, followed by blank and CERT-FILE */
    ca_file = argv[2];
  }
  else {
    usage (argv[0]);
    /* does not return */
  }

  setprogname (argv[0]);
  ri ();

  sk_file = argv[argc - 4];
  cert_file = argv[argc - 3];
  resp_id = argv[argc - 2];
  out_fd = atoi (argv[argc - 1]);

  if (!cert_verify (own_cert = cert_read (cert_file))) {
      fprintf (stderr, "%s: trouble reading certificate from %s, or certificate expired\n",
	      getprogname (), cert_file);
      perror (getprogname ());

      exit (1);
  }
  else {
    to_b = prepare_ke_msg (own_cert, xstrdup (resp_id));
    sk = sk_from_file (sk_file);
    ke_msg1 = export_ke_msg (to_b, sk);
    dcfree (sk);
    sk = NULL;
    write_chunk (1, ke_msg1, strlen (ke_msg1));
    check_n_free ((char **) &ke_msg1);
    ca_pk = pk_from_file (ca_file);
    if (!(ke_msg2 = read_line (0)) 
	|| !(from_b = process_ke_reply (to_b, ke_msg2, ca_pk))) {
      fprintf (stderr, "error reading/parsing bob's message:\n%s", ke_msg2);
      dcfree (ca_pk);
      ca_pk = NULL;
      check_n_free(&ke_msg2);
      
      exit (1);
    }

    dcfree (ca_pk);
    ca_pk = NULL;
    check_n_free(&ke_msg2);

    /* derive_key looks at seskey to know if it the caller is alice or bob */
    seskey[0] = 'a';
    if (derive_key (seskey, to_b, from_b) == -1) {
      fprintf (stderr, "error deriving session key for alice.\n");
      flow1_clr (to_b);
      flow2_clr (from_b);
      
      exit (1);
    }
    else {
      /* choose a random number to send */
      prng_getbytes (secret, aes_blocklen);
      cat_buf (&pretty_secret, secret, aes_blocklen);
      
      /* send it to bob, encrypted under the newly established session key */
      send_secret (1, secret, seskey);

      /* dump the chosen secret to standard error */
      if ((write_chunk (out_fd, pretty_secret, strlen (pretty_secret)) == -1)
	  || (write_chunk (out_fd, "\n", 1) == -1)) {
	fprintf (stderr, "error writing to the launcher.\n");
	bzero (seskey, sha1_hashsize);
	bzero (secret, sizeof (secret));
	bzero (pretty_secret, strlen (pretty_secret));
	xfree (pretty_secret);
	pretty_secret = NULL;
	flow1_clr (to_b);
	flow2_clr (from_b);
	
	exit (1);
      }

      /* wipe out sensitive data */
      bzero (seskey, sha1_hashsize);
      bzero (secret, sizeof (secret));
      bzero (pretty_secret, strlen (pretty_secret));
      xfree (pretty_secret);
      pretty_secret = NULL;
      flow1_clr (to_b);
      flow2_clr (from_b);
    }
  }

  /* fprintf (stderr, "alice:done.\n"); */
  return 0;
}