コード例 #1
0
ファイル: rng.cpp プロジェクト: theihor/crypto2
char gen_bit(int index) {

    char* R = new char[BLOCK_SIZE];
    copy_bytes(I, R); // R = I
    xor_bytes(S, R); // R = I xor S
    //cout << "R = I xor S = "; print_hex(R, BLOCK_SIZE); cout << endl;

    char* X = f(R); // X = f(R, k)
    //cout << "X = f(R, K) = "; print_hex(X, BLOCK_SIZE); cout << endl;
    
    char* T = new char[BLOCK_SIZE];
    copy_bytes(X, T);
    xor_bytes(I, T); // T = X xor I
    //cout << "T = X xor I = "; print_hex(T, BLOCK_SIZE); cout << endl;
    
    S = f(T); // S = f(T, K)
    //cout << "S = f(T, K) = "; print_hex(S, BLOCK_SIZE); cout << endl;
    
    int i = index / 8;
    index %= 8;
   
    char mask = 1;
    mask <<= index;

    char bit = X[i] & mask;
    if (index == 7) {
        bit >>= 1;
        bit &= 0x7f;
        bit >>= index - 1;
    } else {
コード例 #2
0
/*
 * plaintext, message length in byte, ciphertext, associated data, and associated data length in byte tag, and tag length in byte
 */
int ae_encrypt(ae_cxt* cxt, byte* pt, unsigned long long mlen, byte* ct, byte* tag, unsigned long long tlen, int enc_dec)
{
    cxt->pt = pt;
    cxt->ptlen = mlen;
    cxt->ct = ct;
    cxt->ctlen = mlen;
    cxt->tag = tag;
    cxt->tlen = tlen;

    byte* es = cxt->es;
    byte* ts = cxt->ts;


    unsigned long long pc = 0;
    while((pc + STATE_LEN) < mlen){
        if(enc_dec == ENC){ // encryption
            xor_bytes(es, pt+pc, STATE_LEN);
            memcpy(ct+pc, es, STATE_LEN);
        }
        else{ // decryption
            xor_bytes2(pt+pc, ct+pc, es, STATE_LEN);
            memcpy(es, ct+pc, STATE_LEN);
        }
        xor_bytes(ts, es, STATE_LEN);
        present_enc(ts, cxt->userkey);
        /* apply fix1 */
        es[0] |= 0x80;
        present_enc(es, cxt->userkey);
        pc += STATE_LEN;
    }

    /* process the last block */
    unsigned long long lastblocklen = mlen - pc;

    if(lastblocklen > 0){
        if(enc_dec == ENC){ // encryption
            xor_bytes(es, pt+pc, lastblocklen);
            memcpy(ct+pc, es, lastblocklen);
        }
        else{ // decryption
            xor_bytes2(pt+pc, ct+pc, es, lastblocklen);
            memcpy(es, ct+pc, lastblocklen);
        }
        xor_bytes(ts, es, lastblocklen);
        present_enc(ts, cxt->userkey);
    }
    /* encode the adlen and process */
    unsigned long long t_adlen = mlen;
    unsigned long long i;
    for(i = 0; i < sizeof(unsigned long long); i++) {
        ts[STATE_LEN-1-i] ^= t_adlen & 0xff;
        t_adlen >>= 8;
    }
    g(ts);
    present_enc(ts, cxt->userkey);

    memcpy(tag, ts, tlen);
    return SUCCESS;
}
コード例 #3
0
ファイル: rng.cpp プロジェクト: theihor/crypto2
void put_timestamp(char* x) {
    time_t t = time(NULL);
    copy_bytes((char*)&t, x);
    int r = rand();
    xor_bytes((char*)&r, x);
    xor_bytes((char*)&r, x + 4);

}
コード例 #4
0
ファイル: silc.c プロジェクト: 0x64616E69656C/supercop
/* associated data and nonce length in byte
 * nlen should be less than 16 bytes and larger than 0 byte;
 */
int process_ad(ae_cxt* cxt, const byte* ad, unsigned long long adlen, const byte* nonce, unsigned long long nlen)
{
	byte* state = cxt->es;
	AES_KEY *ekey = cxt->pt_ekey;

	cxt->ad = (byte*) ad;
	cxt->adlen = adlen;
	cxt->nonce = (byte*) nonce;
	cxt->nlen = nlen;

	/* process the nonce */
	memset(state, 0, STATE_LEN);
	state[STATE_LEN-nlen-1] = PARAM;
	memcpy(state+STATE_LEN-nlen, nonce, nlen);

	//xor_bytes(state, nonce, nlen);	// xor to the last nlen bytes
	pstate2("processing nonce:", NULL);
	AES_encrypt(state, state, ekey);

	/* process the middle normal blocks of ad */
	unsigned long long i;
	for(i = 0; i < (unsigned long long)adlen/STATE_LEN; i++){
		xor_bytes(state, ad+STATE_LEN*i, STATE_LEN);
		pstate2("After xoring associated data:", state);
		pstate2("Enc:", NULL);
		AES_encrypt(state, state, ekey);
	}
	/* process the last block partial block if any */
	unsigned long long lastblocklen = adlen % STATE_LEN;
	if(lastblocklen){
		xor_bytes(state, ad+i*STATE_LEN, lastblocklen);
		pstate2("After processing last partial associated data block:", state);
		pstate2("Enc:", NULL);
		AES_encrypt(state, state, ekey);
	}

	/* encode the adlen and process */
	unsigned long long t_adlen = adlen;
	for(i = 0; i < sizeof(unsigned long long); i++) {
		state[STATE_LEN-1-i] ^= t_adlen & 0xff;
		t_adlen >>= 8;
	}
	pstate2("After xoring the length of associated data:", state);

	g(state);
	pstate2("After applying g:", state);
	memcpy(cxt->ts, state, STATE_LEN);
	pstate2("Enc:", NULL);
	AES_encrypt(state, state, ekey);

	g(cxt->ts);
	pstate2("After applying g to tag state:", cxt->ts);
	pstate2("Enc:", NULL);
	AES_encrypt(cxt->ts, cxt->ts, ekey);
	return SUCCESS;
}
コード例 #5
0
ファイル: riv.c プロジェクト: medsec/riv
int decrypt_final(riv_context_t* ctx, 
                  const unsigned char* ciphertext,
                  const unsigned long long ciphertext_length, 
                  const unsigned char* header,
                  const unsigned long long header_length, 
                  const unsigned char tag[TAGLEN], 
                  unsigned char* plaintext)
{
    ALIGN(16) uint8_t iv[TAGLEN];
    ALIGN(16) uint8_t iv_prime[TAGLEN];

    clhash(&(ctx->prf_context), 
        header, header_length, DOMAIN_1, ciphertext, ciphertext_length, iv);

    cdms(iv, iv, ctx->expanded_key);
    xor_bytes(iv, iv, tag, TAGLEN);

    cdms(iv_prime, iv, ctx->expanded_key);
    sct_mode(ctx, iv_prime, (const __m128i*)ciphertext, 
        ciphertext_length, (__m128i*)plaintext);
    
    clhash(&(ctx->prf_context), 
        header, header_length, DOMAIN_0, plaintext, ciphertext_length, iv_prime);

    cdms(iv_prime, iv_prime, ctx->expanded_key);
    return (_mm_testc_si128(load(iv), load(iv_prime)) - 1)
        | (_mm_testc_si128(load((iv+BLOCKLEN)), load((iv_prime+BLOCKLEN))) - 1);
}
コード例 #6
0
ファイル: riv.c プロジェクト: medsec/riv
void encrypt_final(riv_context_t* ctx, 
                   const unsigned char* plaintext,
                   const unsigned long long plaintext_length, 
                   const unsigned char* header,
                   const unsigned long long header_length, 
                   unsigned char* ciphertext, 
                   unsigned char tag[TAGLEN])
{
    ALIGN(16) uint8_t iv[TAGLEN];
    ALIGN(16) uint8_t s[TAGLEN];

    clhash(&(ctx->prf_context), header, header_length, DOMAIN_0, 
        plaintext, plaintext_length, iv);

    cdms(iv, iv, ctx->expanded_key);

    ALIGN(16) uint8_t iv_prime[TAGLEN];
    cdms(iv_prime, iv, ctx->expanded_key);

    sct_mode(ctx, iv_prime, (const __m128i*)plaintext, 
        plaintext_length, (__m128i*)ciphertext);
    
    clhash(&(ctx->prf_context), 
        header, header_length, DOMAIN_1, ciphertext, plaintext_length, s);
    
    cdms(s, s, ctx->expanded_key);
    xor_bytes(tag, s, iv, TAGLEN);
}
コード例 #7
0
ファイル: aes_modes.c プロジェクト: iburinoc/ibcrypt
int encrypt_cbc_AES(const uint8_t *const message, const uint32_t length, const uint8_t *const iv, const AES_KEY *const key, uint8_t *const out) {
	if(length % 16 != 0) {
		return -1; // must be of proper size
	}
	
	uint8_t prev[16];
	memcpy(prev, iv, 16); // set up init vector
	
	uint8_t encbuf[16];
	
	for(uint32_t i = 0; i < length / 16; i++) {
		xor_bytes(message + i  *16, prev, 16, encbuf); // xor in iv
		encrypt_block_AES(encbuf, prev, key); // encrypt block
		memcpy(out + i  *16, prev, 16); // copy to output
	}
	return 0;
}
コード例 #8
0
ファイル: aes_modes.c プロジェクト: iburinoc/ibcrypt
int decrypt_cbc_AES(const uint8_t *const message, const uint32_t length, const uint8_t *const iv, const AES_KEY *const key, uint8_t *const out) {
	if(length % 16 != 0) {
		return -1; // must be of proper size
	}
	
	uint8_t prev[16];
	memcpy(prev, iv, 16); // set up init vector
	
	uint8_t decbuf[16];
	
	for(uint32_t i = 0; i < length / 16; i++) {
		decrypt_block_AES(message + i  *16, decbuf, key); // decrypt block
		xor_bytes(decbuf, prev, 16, out + i  *16); // write to output
		memcpy(prev, message + i  *16, 16); // copy ciphertext for next prev
	}
	
	return 0;
}
コード例 #9
0
/*!
 * @brief Receive a new packet on the given remote endpoint.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to a pointer that will receive the \c Packet data.
 * @return An indication of the result of processing the transmission request.
 */
static DWORD packet_receive_named_pipe(Remote *remote, Packet **packet)
{
	DWORD headerBytes = 0, payloadBytesLeft = 0, res;
	PacketHeader header = { 0 };
	LONG bytesRead;
	BOOL inHeader = TRUE;
	PUCHAR packetBuffer = NULL;
	PUCHAR payload = NULL;
	ULONG payloadLength;
	NamedPipeTransportContext* ctx = (NamedPipeTransportContext*)remote->transport->ctx;

	lock_acquire(remote->lock);

	dprintf("[PIPE PACKET RECEIVE] reading in the header from pipe handle: %p", ctx->pipe);
	// Read the packet length
	while (inHeader)
	{
		if (!ReadFile(ctx->pipe, ((PUCHAR)&header + headerBytes), sizeof(PacketHeader)-headerBytes, &bytesRead, NULL))
		{
			SetLastError(ERROR_NOT_FOUND);
			goto out;
		}

		headerBytes += bytesRead;

		if (headerBytes != sizeof(PacketHeader))
		{
			vdprintf("[PIPE] More bytes required");
			continue;
		}

		inHeader = FALSE;
	}

	if (headerBytes != sizeof(PacketHeader))
	{
		dprintf("[PIPE] we didn't get enough header bytes");
		goto out;
	}

	vdprintf("[PIPE] the XOR key is: %02x%02x%02x%02x", header.xor_key[0], header.xor_key[1], header.xor_key[2], header.xor_key[3]);

#ifdef DEBUGTRACE
	PUCHAR h = (PUCHAR)&header;
	dprintf("[PIPE] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]",
		h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]);
#endif

	// At this point, we might have read in a valid TLV packet, or we might have read in the first chunk of data
	// from a staged listener after a reconnect. We can figure this out rather lazily by assuming the following:
	// XOR keys are always 4 bytes that are non-zero. If the higher order byte of the xor key is zero, then it
	// isn't an XOR Key, instead it's the 4-byte length of the metsrv binary (because metsrv isn't THAT big).
	if (header.xor_key[3] == 0)
	{
		// looks like we have a metsrv instance, time to ignore it.
		int length = *(int*)&header.xor_key[0];
		dprintf("[PIPE] discovered a length header, assuming it's metsrv of length %d", length);

		int bytesToRead = length - sizeof(PacketHeader) + sizeof(DWORD);
		char* buffer = (char*)malloc(bytesToRead);
		read_raw_bytes_to_buffer(ctx, buffer, bytesToRead, &bytesRead);
		free(buffer);

		// did something go wrong.
		if (bytesToRead != bytesRead)
		{
			dprintf("[PIPE] Failed to read all bytes when flushing the buffer: %u vs %u", bytesToRead, bytesRead);
			goto out;
		}

		// indicate success, but don't return a packet for processing
		SetLastError(ERROR_SUCCESS);
		*packet = NULL;
	}
	else
	{
		vdprintf("[PIPE] XOR key looks fine, moving on");
		// xor the header data
		xor_bytes(header.xor_key, (PUCHAR)&header + sizeof(header.xor_key), sizeof(PacketHeader) - sizeof(header.xor_key));
#ifdef DEBUGTRACE
		PUCHAR h = (PUCHAR)&header;
		dprintf("[PIPE] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]",
			h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]);
#endif

		// if we don't have a GUID yet, we need to take the one given in the packet
		if (is_null_guid(remote->orig_config->session.session_guid))
		{
			memcpy(remote->orig_config->session.session_guid, header.session_guid, sizeof(remote->orig_config->session.session_guid));
		}

		payloadLength = ntohl(header.length) - sizeof(TlvHeader);
		dprintf("[PIPE] Payload length is %u 0x%08x", payloadLength, payloadLength);
		DWORD packetSize = sizeof(PacketHeader) + payloadLength;
		dprintf("[PIPE] total buffer size for the packet is %u 0x%08x", packetSize, packetSize);
		payloadBytesLeft = payloadLength;

		// Allocate the payload
		if (!(packetBuffer = (PUCHAR)malloc(packetSize)))
		{
			dprintf("[PIPE] Failed to create the packet buffer");
			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
			goto out;
		}
		dprintf("[PIPE] Allocated packet buffer at %p", packetBuffer);

		// we're done with the header data, so we need to re-encode it, as the packet decryptor is going to
		// handle the extraction for us.
		xor_bytes(header.xor_key, (LPBYTE)&header.session_guid[0], sizeof(PacketHeader) - sizeof(header.xor_key));
		// Copy the packet header stuff over to the packet
		memcpy_s(packetBuffer, sizeof(PacketHeader), (LPBYTE)&header, sizeof(PacketHeader));

		payload = packetBuffer + sizeof(PacketHeader);

		// Read the payload
		res = read_raw_bytes_to_buffer(ctx, payload, payloadLength, &bytesRead);
		dprintf("[PIPE] wanted %u read %u", payloadLength, bytesRead);

		// Didn't finish?
		if (bytesRead != payloadLength)
		{
			dprintf("[PIPE] Failed to get all the payload bytes");
			SetLastError(res);
			goto out;
		}

		vdprintf("[PIPE] decrypting packet");
		SetLastError(decrypt_packet(remote, packet, packetBuffer, packetSize));

		free(packetBuffer);
		packetBuffer = NULL;
	}
out:
	res = GetLastError();

	// Cleanup
	if (packetBuffer)
	{
		free(packetBuffer);
	}

	lock_release(remote->lock);

	return res;
}
コード例 #10
0
ファイル: cloc.c プロジェクト: 0x64616E69656C/supercop
/* associated data and nonce length in byte
 * nlen should be less than 16 bytes and larger than 0 byte;
 */
int process_ad(ae_cxt* cxt, const byte* ad, unsigned long long adlen, const byte* nonce, unsigned long long nlen)
{
	byte* state = cxt->es;

	cxt->ad = (byte*) ad;
	cxt->adlen = adlen;
	cxt->nonce = (byte*) nonce;
	cxt->nlen = nlen;
	/* process the first block */
	int ozp = 0;
	if(adlen < STATE_LEN){       // less than one block
		memcpy(state, ad, adlen);
		memset(state+adlen, 0, STATE_LEN-adlen);
		state[adlen] = 0x80;
		ozp = 1;                // one-zero padding works only if the adlen < 16
	}
	else{                       // full first block
		memcpy(state, ad, STATE_LEN);
	}

	/* apply fix0 and the E_k */
	int fix0 = state[0] & 0x80;    /* test if the MSB is zero */
	state[0] &= 0x7f;

	/* apply the first encryption */
	Encode(state, state);
	/* when fix0 works, apply h */
	if(fix0){
		word* wd = (word*) state;
		h(wd[0], wd[1], wd[2], wd[3]);
	}
	else{
		// do nothing
	}

	/* process the middle normal blocks of ad */
	unsigned long long i;
	for(i = 1; i < (unsigned long long)adlen/STATE_LEN; i++){
		xor_bytes(state, ad+i*STATE_LEN, STATE_LEN);
		pstate2("After xoring associated data:", state);
		Encode(state, state);
	}
	/* process the last block partial block if any */
	unsigned long long lastblocklen = adlen % STATE_LEN;
	if((adlen > STATE_LEN) && lastblocklen){
		xor_bytes(state, ad+i*STATE_LEN, lastblocklen);
		state[lastblocklen] ^= 0x80;
		pstate2("After processing last partial associated data block:", state);
		Encode(state, state);
		ozp = 1;
	}

	/* process the nonce */
	xor_bytes(state, nonce, nlen);

	/* apply padding to nonce */
	if(nlen != STATE_LEN)
		state[nlen] ^= 0x80;

	/* apply f1 or f2 to get V */
	if(ozp){ // apply f2
		word* wd = (word*) state;
		f2(wd[0], wd[1], wd[2], wd[3]);
	}
	else{ // apply f1
		word* wd = (word*) state;
		f1(wd[0], wd[1], wd[2], wd[3]);
	}
	pstate2("After applying f1/f2 to state:", state);

	memcpy(cxt->ts, state, STATE_LEN);
	Encode(state, state);

	return SUCCESS;
}
コード例 #11
0
/*!
 * @brief Windows-specific function to receive a new packet via one of the HTTP libs (WinInet or WinHTTP).
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to a pointer that will receive the \c Packet data.
 * @return An indication of the result of processing the transmission request.
 */
static DWORD packet_receive_http(Remote *remote, Packet **packet)
{
	DWORD headerBytes = 0, payloadBytesLeft = 0, res;
	Packet *localPacket = NULL;
	PacketHeader header;
	LONG bytesRead;
	BOOL inHeader = TRUE;
	PUCHAR packetBuffer = NULL;
	ULONG payloadLength;
	HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;

	HINTERNET hReq;
	BOOL hRes;
	DWORD retries = 5;

	lock_acquire(remote->lock);

	hReq = ctx->create_req(ctx, TRUE, "PACKET RECEIVE");
	if (hReq == NULL)
	{
		goto out;
	}

	vdprintf("[PACKET RECEIVE HTTP] sending GET");
	hRes = ctx->send_req(ctx, hReq, NULL, 0);

	if (!hRes)
	{
		dprintf("[PACKET RECEIVE HTTP] Failed send_req: %d %d", GetLastError(), WSAGetLastError());
		SetLastError(ERROR_NOT_FOUND);
		goto out;
	}

	vdprintf("[PACKET RECEIVE HTTP] Waiting to see the response ...");
	if (ctx->receive_response && !ctx->receive_response(hReq))
	{
		vdprintf("[PACKET RECEIVE] Failed receive: %d", GetLastError());
		SetLastError(ERROR_NOT_FOUND);
		goto out;
	}

	SetLastError(ctx->validate_response(hReq, ctx));

	if (GetLastError() != ERROR_SUCCESS)
	{
		goto out;
	}

	// Read the packet length
	retries = 3;
	vdprintf("[PACKET RECEIVE HTTP] Start looping through the receive calls");
	while (inHeader && retries > 0)
	{
		retries--;
		if (!ctx->read_response(hReq, (PUCHAR)&header + headerBytes, sizeof(PacketHeader)-headerBytes, &bytesRead))
		{
			dprintf("[PACKET RECEIVE HTTP] Failed HEADER read_response: %d", GetLastError());
			SetLastError(ERROR_NOT_FOUND);
			goto out;
		}

		vdprintf("[PACKET RECEIVE NHTTP] Data received: %u bytes", bytesRead);

		// If the response contains no data, this is fine, it just means the
		// remote side had nothing to tell us. Indicate this through a
		// ERROR_EMPTY response code so we can update the timestamp.
		if (bytesRead == 0)
		{
			SetLastError(ERROR_EMPTY);
			goto out;
		}

		headerBytes += bytesRead;

		if (headerBytes != sizeof(PacketHeader))
		{
			continue;
		}

		inHeader = FALSE;
	}

	if (headerBytes != sizeof(PacketHeader))
	{
		dprintf("[PACKET RECEIVE HTTP] headerBytes not valid");
		SetLastError(ERROR_NOT_FOUND);
		goto out;
	}

	dprintf("[PACKET RECEIVE HTTP] decoding header");
	PacketHeader encodedHeader;
	memcpy(&encodedHeader, &header, sizeof(PacketHeader));
	xor_bytes(header.xor_key, (PUCHAR)&header + sizeof(header.xor_key), sizeof(PacketHeader) - sizeof(header.xor_key));

#ifdef DEBUGTRACE
	PUCHAR h = (PUCHAR)&header;
	vdprintf("[HTTP] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]",
		   h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]);
#endif

	payloadLength = ntohl(header.length) - sizeof(TlvHeader);
	vdprintf("[REC HTTP] Payload length is %d", payloadLength);
	DWORD packetSize = sizeof(PacketHeader) + payloadLength;
	vdprintf("[REC HTTP] total buffer size for the packet is %d", packetSize);
	payloadBytesLeft = payloadLength;

	// Allocate the payload
	if (!(packetBuffer = (PUCHAR)malloc(packetSize)))
	{
		dprintf("[REC HTTP] Failed to create the packet buffer");
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		goto out;
	}
	dprintf("[REC HTTP] Allocated packet buffer at %p", packetBuffer);

	// Copy the packet header stuff over to the packet
	memcpy_s(packetBuffer, sizeof(PacketHeader), (LPBYTE)&encodedHeader, sizeof(PacketHeader));

	LPBYTE payload = packetBuffer + sizeof(PacketHeader);

	// Read the payload
	retries = payloadBytesLeft;
	while (payloadBytesLeft > 0 && retries > 0)
	{
		vdprintf("[PACKET RECEIVE HTTP] reading more data from the body...");
		retries--;
		if (!ctx->read_response(hReq, payload + payloadLength - payloadBytesLeft, payloadBytesLeft, &bytesRead))
		{
			dprintf("[PACKET RECEIVE] Failed BODY read_response: %d", GetLastError());
			SetLastError(ERROR_NOT_FOUND);
			goto out;
		}

		if (!bytesRead)
		{
			vdprintf("[PACKET RECEIVE HTTP] no bytes read, bailing out");
			SetLastError(ERROR_NOT_FOUND);
			goto out;
		}

		vdprintf("[PACKET RECEIVE HTTP] bytes read: %u", bytesRead);
		payloadBytesLeft -= bytesRead;
	}

	// Didn't finish?
	if (payloadBytesLeft)
	{
		goto out;
	}

#ifdef DEBUGTRACE
	h = (PUCHAR)&header.session_guid[0];
	dprintf("[HTTP] Packet Session GUID: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
		h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15]);
#endif

	if (is_null_guid(header.session_guid) || memcmp(remote->orig_config->session.session_guid, header.session_guid, sizeof(header.session_guid)) == 0)
	{
		dprintf("[HTTP] Session GUIDs match (or packet guid is null), decrypting packet");
		SetLastError(decrypt_packet(remote, packet, packetBuffer, packetSize));
	}
	else
	{
		dprintf("[HTTP] Session GUIDs don't match, looking for a pivot");
		PivotContext* pivotCtx = pivot_tree_find(remote->pivot_sessions, header.session_guid);
		if (pivotCtx != NULL)
		{
			dprintf("[HTTP] Pivot found, dispatching packet on a thread (to avoid main thread blocking)");
			SetLastError(pivot_packet_dispatch(pivotCtx, packetBuffer, packetSize));

			// mark this packet buffer as NULL as the thread will clean it up
			packetBuffer = NULL;
			*packet = NULL;
		}
		else
		{
			dprintf("[HTTP] Session GUIDs don't match, can't find pivot!");
		}
	}

out:
	res = GetLastError();

	dprintf("[HTTP] Cleaning up");
	SAFE_FREE(packetBuffer);

	// Cleanup on failure
	if (res != ERROR_SUCCESS)
	{
		SAFE_FREE(localPacket);
	}

	if (hReq)
	{
		ctx->close_req(hReq);
	}

	lock_release(remote->lock);

	dprintf("[HTTP] Packet receive finished");

	return res;
}
コード例 #12
0
ファイル: rsa.c プロジェクト: iburinoc/ibcrypt
int rsa_pss_verify(RSA_PUBLIC_KEY *key, uint8_t *sig, size_t siglen, uint8_t *message, size_t mlen, int *valid) {
	if(key == NULL || sig == NULL || message == NULL || valid == NULL) {
		return -1;
	}

	const size_t emlen = (key->bits - 2) / 8 + 1;
	const size_t hlen = 32;
	const size_t slen = hlen;
	SHA256_CTX ctx;
	uint8_t hash[hlen];
	uint8_t zeroes[8];
	uint8_t *em = NULL;
	uint8_t *mask = NULL;
	bignum em_bn = BN_ZERO;
	bignum s_bn = BN_ZERO;

	int ret;

	*valid = 0;

	if((em = malloc(emlen)) == NULL) {
		return MALLOC_FAIL;
	}

	if((mask = malloc(emlen - hlen - 1)) == NULL) {
		ret = MALLOC_FAIL;
		goto err;
	}

	if((ret = os2ip(&s_bn, sig, siglen)) != 0) {
		/* cleanup is non-necessary here, but no harm */
		goto err;
	}

	if((ret = rsa_encrypt(key, &s_bn, &em_bn)) != 0) {
		goto err;
	}

	if((ret = i2osp(em, emlen, &em_bn)) != 0) {
		goto err;
	}

	mgf1_sha256(&em[emlen - hlen - 1], hlen, emlen - hlen - 1, mask);

	xor_bytes(em, mask, emlen - hlen - 1, em);

	sha256_init(&ctx);
	sha256_update(&ctx, message, mlen);
	sha256_final(&ctx, hash);

	memset(zeroes, 0x00, 8);

	sha256_init(&ctx);
	sha256_update(&ctx, zeroes, 8);
	sha256_update(&ctx, hash, hlen);
	sha256_update(&ctx, &em[emlen - hlen - slen - 1], slen);
	sha256_final(&ctx, hash);

	xor_bytes(&em[emlen - hlen - 1], hash, hlen, &em[emlen - hlen - 1]);
	em[emlen - hlen - slen - 2] ^= 0x01;
	em[emlen - 1] ^= 0xbc;
	em[0] &= ((uint8_t) 0xff) >> (emlen * 8 - (key->bits - 2));
	memset(&em[emlen - hlen - slen - 1], 0x00, slen);

	size_t i;
	uint8_t val = 0;
	for(i = 0; i < emlen; i++) {
		val |= (em[i]);
	}

	if(val) {
		*valid = 0;
	} else {
		*valid = 1;
	}

	ret = 0;

err:
	memsets(&ctx, 0x00, sizeof(SHA256_CTX));
	memsets(hash, 0x00, hlen);
	if(em) zfree(em, emlen);
	if(mask) zfree(mask, emlen - hlen - 1);
	bnu_free(&em_bn);
	bnu_free(&s_bn);

	return ret;
}
コード例 #13
0
ファイル: cloc.c プロジェクト: 0x64616E69656C/supercop
/*
 * plaintext, message length in byte, ciphertext, associated data, and associated data length in byte tag, and tag length in byte
 */
int ae_encrypt(ae_cxt* cxt, byte* pt, unsigned long long mlen, byte* ct, byte* tag, unsigned long long tlen, int enc_dec)
{
	cxt->pt = pt;
	cxt->ptlen = mlen;
	cxt->ct = ct;
	cxt->ctlen = mlen;
	cxt->tag = tag;
	cxt->tlen = tlen;

	byte* es = cxt->es;
	byte* ts = cxt->ts;

	word* wd = (word*) ts;
	if(mlen != 0){
		g2(wd[0], wd[1], wd[2], wd[3]);
		Encode(cxt->ts, cxt->ts);
	}
	else{
		g1(wd[0], wd[1], wd[2], wd[3]);
		Encode(cxt->ts, cxt->ts);
		memcpy(tag, ts, tlen);
		return SUCCESS;
	}


	unsigned long long pc = 0;
	while((pc + STATE_LEN) < mlen){
		if(enc_dec == ENC){ // encryption
			xor_bytes(es, pt+pc, STATE_LEN);
			pstate2("After xoring message block:", es);
			memcpy(ct+pc, es, STATE_LEN);
		}
		else{ // decryption
			xor_bytes2(pt+pc, ct+pc, es, STATE_LEN);
			pstate2("After xoring ciphertext block:", es);
			memcpy(es, ct+pc, STATE_LEN);
		}
		xor_bytes(ts, es, STATE_LEN);
		Encode(ts, ts);
		/* apply fix1 */
		es[0] |= 0x80;
		pstate2("After applying fix1:", es);
		Encode(es, es);
		pc += STATE_LEN;
	}

	/* process the last block */
	unsigned long long lastblocklen = mlen - pc;
	if(enc_dec == ENC){ // encryption
		xor_bytes(es, pt+pc, lastblocklen);
		pstate2("After xoring last partial message block:", es);
		memcpy(ct+pc, es, lastblocklen);
	}
	else{ // decryption
		xor_bytes2(pt+pc, ct+pc, es, lastblocklen);
		pstate2("After xoring last partial ciphertext block:", es);
		memcpy(es, ct+pc, lastblocklen);
	}
	xor_bytes(ts, es, lastblocklen);
	pstate2("tag state:", ts);
	if(lastblocklen != STATE_LEN){ // apply f2
		/* apply padding only when last message block is not full */
		ts[lastblocklen] ^= 0x80;
		word* wd = (word*) ts;
		f2(wd[0], wd[1], wd[2], wd[3]);
	}
	else{ // apply f1
		word* wd = (word*) ts;
		f1(wd[0], wd[1], wd[2], wd[3]);
	}

	pstate2("After applying f1/f2:", ts);
	Encode(ts, ts);
	memcpy(tag, ts, tlen);

	return SUCCESS;
}
コード例 #14
0
ファイル: rsa.c プロジェクト: iburinoc/ibcrypt
int rsa_oaep_decrypt(RSA_KEY *key, uint8_t *ctext, size_t clen, uint8_t *out, size_t outlen) {
	if(key == NULL || ctext == NULL || out == NULL) {
		return -1;
	}

	const size_t k = (key->bits - 1) / 8 + 1;
	const size_t hlen = 32;
	bignum c_bn = BN_ZERO;
	bignum m_bn = BN_ZERO;
	uint8_t *em = NULL;
	uint8_t *db = NULL;
	uint8_t *mask = NULL;
	uint8_t seed[hlen];
	size_t message_start;

	int ret;

	/* nothing critical yet */
	if((ret = os2ip(&c_bn, ctext, clen)) != 0) {
		return ret;
	}

	/* now sensitive information is contained in our buffers, so we have
	 * to clean up */
	if((ret = rsa_decrypt(key, &c_bn, &m_bn)) != 0) {
		goto err;
	}

	if((em = malloc(k)) == NULL) {
		ret = MALLOC_FAIL;
		goto err;
	}

	if((ret = i2osp(em, k, &m_bn)) != 0) {
		goto err;
	}
	db = em + hlen + 1;

	if((mask = malloc(k - hlen - 1)) == NULL) {
		ret = MALLOC_FAIL;
		goto err;
	}

	/* calculate seed mask = MGF1(maskedDB, k - hlen - 1) */
	mgf1_sha256(db, k - hlen - 1, hlen, mask);

	/* calculate seed */
	xor_bytes(em + 1, mask, hlen, seed);

	/* calculate dbMask */
	mgf1_sha256(seed, hlen, k - hlen - 1, mask);

	/* unmask db */
	xor_bytes(db, mask, k - hlen - 1, db);

	/* find the start of the message */
	for(message_start = hlen; message_start < k - hlen - 1 &&
		db[message_start] == 0x00; message_start++) {}

	uint8_t valid = 0;
	valid |= memcmp_ct(db, lhash, 32);
	valid |= em[0];
	valid |= !(message_start != k - hlen - 1 && db[message_start] == 1);

	/* if valid is non-zero this is not a valid message */
	if(valid != 0) {
		ret = CRYPTOGRAPHY_ERROR;
		goto err;
	}

	message_start++;

	/* prevent buffer overflows */
	if(outlen < k - hlen - 1 - message_start) {
		ret = TOO_SHORT;
		goto err;
	}
	memcpy(out, &db[message_start], k - hlen - 1 - message_start);

	ret = 0;
err:
	ret = ret == 0 ? bnu_free(&c_bn) : ret;
	ret = ret == 0 ? bnu_free(&m_bn) : ret;
	if(em) zfree(em, k);
	if(mask) zfree(mask, k - hlen - 1);
	memsets(seed, 0x00, hlen);

	return ret;
}
コード例 #15
0
ファイル: rsa.c プロジェクト: iburinoc/ibcrypt
int rsa_pss_sign(RSA_KEY *key, uint8_t *message, size_t mlen, uint8_t *out, size_t outlen) {
	if(key == NULL || message == NULL || out == NULL) {
		return -1;
	}

	const size_t k = (key->bits - 1) / 8 + 1;
	const size_t emlen = (key->bits - 2) / 8 + 1;
	const size_t hlen = 32;
	const size_t slen = hlen;
	SHA256_CTX ctx;
	uint8_t mhash[hlen];
	uint8_t salt[slen];
	uint8_t zeroes[8];
	uint8_t *em = NULL;
	bignum em_bn = BN_ZERO;
	bignum s_bn = BN_ZERO;

	int ret;

	if(outlen < k) {
		/* avoid buffer overflows */
		return TOO_SHORT;
	}

	if(emlen < hlen + slen + 2) {
		/* key too small to sign */
		return CRYPTOGRAPHY_ERROR;
	}

	/* allocate space for em */
	if((em = malloc(emlen)) == NULL) {
		return MALLOC_FAIL;
	}

	/* generate salt, as we can still exit without cleanup if this fails */
	if(cs_rand(salt, slen) != 0) {
		return CRYPTOGRAPHY_ERROR;
	}

	sha256_init(&ctx);
	sha256_update(&ctx, message, mlen);
	sha256_final(&ctx, mhash);

	/* calculate H = sha256(0x00 00 00 00 00 00 00 00 || mhash || salt) */
	memset(zeroes, 0x00, 8);

	sha256_init(&ctx);
	sha256_update(&ctx, zeroes, 8);
	sha256_update(&ctx, mhash, hlen);
	sha256_update(&ctx, salt, slen);
	sha256_final(&ctx, &em[emlen - hlen - 1]);

	mgf1_sha256(&em[emlen - hlen - 1], hlen, emlen - hlen - 1, em);

	/* xor in 0x01 and salt */
	em[emlen - slen - hlen - 2] ^= 0x01;
	xor_bytes(&em[emlen - slen - hlen - 1], salt, slen, &em[emlen - slen - hlen - 1]);
	em[emlen - 1] = 0xbc;

	em[0] &= ((uint8_t) 0xff) >> (8 * emlen - (key->bits - 2));

	if((ret = os2ip(&em_bn, em, emlen)) != 0) {
		goto err;
	}

	if((ret = rsa_decrypt(key, &em_bn, &s_bn)) != 0) {
		goto err;
	}

	if((ret = i2osp(out, outlen, &s_bn)) != 0) {
		goto err;
	}

	ret = 0;
err:
	memsets(mhash, 0, hlen);
	memsets(salt, 0, slen);
	memsets(&ctx, 0, sizeof(SHA256_CTX));
	bnu_free(&s_bn);
	bnu_free(&em_bn);
	if(em) zfree(em, emlen);

	return ret;
}
コード例 #16
0
ファイル: rsa.c プロジェクト: iburinoc/ibcrypt
int rsa_oaep_encrypt(RSA_PUBLIC_KEY *key, uint8_t *message, size_t mlen, uint8_t *out, size_t outlen) {
	if(key == NULL || message == NULL || out == NULL) {
		return -1;
	}

	const size_t k = (key->bits - 1) / 8 + 1;
	const size_t hlen = 32;
	uint8_t seed[hlen];
	uint8_t *mask;
	uint8_t *em;
	uint8_t *db;
	bignum m_bn;
	bignum c_bn;

	int ret;

	/* message is too long to encrypt */
	if(k - 2 * hlen - 2 < mlen) {
		return TOO_LONG;
	}

	/* output buffer is too small */
	if(outlen < k) {
		return TOO_SHORT;
	}

	/* do stuff involving the masks first, as in case of error it does not
	 * need to be kept secure */
	if(cs_rand(seed, hlen) != 0) {
		return CRYPTOGRAPHY_ERROR;
	}

	if((mask = malloc(k - hlen - 1)) == NULL) {
		return MALLOC_FAIL;
	}

	/* calculate dbMask = MGF(seed, k - hLen - 1) */
	mgf1_sha256(seed, hlen, k - hlen - 1, mask);

	/* now initialize the string to be encrypted */
	if((em = malloc(k)) == NULL) {
		return MALLOC_FAIL;
	}

	/* from now on we have to clean up memory after any failures */
	/* em[hlen:] is all DB = lhash || PS || 0x01 || M */
	db = em + hlen + 1;
	memcpy(db, lhash, hlen);
	/* PS is a padding string of zeroes */
	memset(db + hlen, 0x00, k - 2 * hlen - mlen - 2);
	/* there is then one byte of value 0x01 */
	db[k - 2 - hlen - mlen] = 0x01;
	/* then message */
	memcpy(&db[k - hlen - 1 - mlen], message, mlen);

	/* now apply the mask to it */
	xor_bytes(db, mask, k - hlen - 1, db);

	/* now we can repurpose mask to encode the seed mask */
	mgf1_sha256(db, k - hlen - 1, hlen, mask);
	/* xor it into em */
	xor_bytes(seed, mask, hlen, em + 1);

	em[0] = 0x00;

	m_bn = BN_ZERO;
	c_bn = BN_ZERO;
	/* now convert to a big integer */
	if((ret = os2ip(&m_bn, em, k)) != 0) {
		goto err;
	}

	/* encrypt */
	if((ret = rsa_encrypt(key, &m_bn, &c_bn)) != 0) {
		goto err;
	}

	/* convert back */
	if((ret = i2osp(out, outlen, &c_bn)) != 0) {
		goto err;
	}

	/* encryption is officially done, clean up */
	ret = 0;

err:
	/* free mask and em, zero seed */
	zfree(mask, k - hlen - 1);
	zfree(em, k - 1);
	memsets(seed, 0x00, hlen);

	/* free the bignums */
	/* an error here is still an error as it is a possible leak of
	 * sensitive data */
	ret = ret == 0 ? bnu_free(&m_bn) : ret;
	ret = ret == 0 ? bnu_free(&c_bn) : ret;

	return ret;
}
コード例 #17
0
ファイル: silc.c プロジェクト: 0x64616E69656C/supercop
/*
 * plaintext, message length in byte, ciphertext, associated data, and associated data length in byte tag, and tag length in byte
 */
int ae_encrypt(ae_cxt* cxt, byte* pt, unsigned long long mlen, byte* ct, byte* tag, unsigned long long tlen, int enc_dec)
{
	cxt->pt = pt;
	cxt->ptlen = mlen;
	cxt->ct = ct;
	cxt->ctlen = mlen;
	cxt->tag = tag;
	cxt->tlen = tlen;

	byte* es = cxt->es;
	byte* ts = cxt->ts;
	AES_KEY *ekey = cxt->pt_ekey;


	unsigned long long pc = 0;
	while((pc + STATE_LEN) < mlen){
		if(enc_dec == ENC){ // encryption
			xor_bytes(es, pt+pc, STATE_LEN);
			pstate2("After xoring message block:", es);
			memcpy(ct+pc, es, STATE_LEN);
		}
		else{ // decryption
			xor_bytes2(pt+pc, ct+pc, es, STATE_LEN);
			pstate2("After xoring ciphertext block:", es);
			memcpy(es, ct+pc, STATE_LEN);
		}
		xor_bytes(ts, es, STATE_LEN);
		pstate2("tag state:", ts);
		pstate2("Enc:", NULL);
		AES_encrypt(ts, ts, ekey);
		/* apply fix1 */
		es[0] |= 0x80;
		pstate2("After applying fix1:", es);
		pstate2("Enc:", NULL);
		AES_encrypt(es, es, ekey);
		pc += STATE_LEN;
	}

	/* process the last block */
	unsigned long long lastblocklen = mlen - pc;

	if(lastblocklen > 0){
		if(enc_dec == ENC){ // encryption
			xor_bytes(es, pt+pc, lastblocklen);
			pstate2("After xoring last partial message block:", es);
			memcpy(ct+pc, es, lastblocklen);
		}
		else{ // decryption
			xor_bytes2(pt+pc, ct+pc, es, lastblocklen);
			pstate2("After xoring last partial ciphertext block:", es);
			memcpy(es, ct+pc, lastblocklen);
		}
		xor_bytes(ts, es, lastblocklen);
		pstate2("tag state:", ts);
		pstate2("Enc:", NULL);
		AES_encrypt(ts, ts, ekey);
	}
	/* encode the adlen and process */
	unsigned long long t_adlen = mlen;
	unsigned long long i;
	for(i = 0; i < sizeof(unsigned long long); i++) {
		ts[STATE_LEN-1-i] ^= t_adlen & 0xff;
		t_adlen >>= 8;
	}
	pstate2("After xoring the legnth of message:", ts);
	g(ts);
	pstate2("After applying g:", ts);
	pstate2("Enc:", NULL);
	AES_encrypt(ts, ts, ekey);

	memcpy(tag, ts, tlen);
	return SUCCESS;
}
コード例 #18
0
ファイル: digitech_xc0324.c プロジェクト: pm-cz/rtl_433
/// @param *data : returns the decoded information as a data_t * 
static int decode_xc0324_message(r_device *decoder, bitbuffer_t *bitbuffer,
  unsigned row, uint16_t bitpos, const int latest_event, data_t **data)
{
    uint8_t b[XC0324_MESSAGE_BYTELEN];
    char id [4] = {0};
    double temperature;
    uint8_t flags;
    uint8_t chksum; // == 0x00 for a good message
    
    // Extract the message
    bitbuffer_extract_bytes(bitbuffer, row, bitpos, b, XC0324_MESSAGE_BITLEN);

    // Examine the chksum and bail out now if not OK to save time
    // b[5] is a check byte, the XOR of bytes 0-4.
    // ie a checksum where the sum is "binary add no carry"
    // Effectively, each bit of b[5] is the parity of the bits in the
    // corresponding position of b[0] to b[4]
    // NB : b[0] ^ b[1] ^ b[2] ^ b[3] ^ b[4] ^ b[5] == 0x00 for a clean message
    chksum = xor_bytes(b, 6);
    if (chksum != 0x00) {
        if (decoder->verbose == 1) {
            // Output the "bad" message (only for message level deciphering!)
            decoder_output_bitrowf(decoder, b, XC0324_MESSAGE_BITLEN,
              "chksum = 0x%02X not 0x00 <- XC0324:vv row %d bit %d",
              chksum, row, bitpos);
        }
        return 0;  // No message was able to be decoded
    }
    
    // Extract the id as hex string
    snprintf(id, 3, "%02X", b[1]);
    
    // Decode temperature (b[2]), plus 1st 4 bits b[3], LSB first order!
    // Tenths of degrees C, offset from the minimum possible (-40.0 degrees)
    uint16_t temp = ((uint16_t)(reverse8(b[3]) & 0x0f) << 8) | reverse8(b[2]) ;
    temperature = (temp / 10.0) - 40.0 ;
    
    //Unknown byte, constant as 0x80 in all my data
    // ??maybe battery status??
    flags = b[4];
    
    // Create the data structure, ready for the decoder_output_data function.
    // Separate production output (decoder->verbose == 0)
    // from (simulated) deciphering stage output (decoder->verbose > 0)
    if (!decoder->verbose) { // production output 
        *data = data_make(
            "model",          "Device Type",     DATA_STRING, "Digitech XC0324",
            "id",             "ID",              DATA_STRING, id,
            "temperature_C",  "Temperature C",   DATA_FORMAT, "%.1f", DATA_DOUBLE, temperature,
            "flags",          "Constant ?",      DATA_INT,    flags,
            "mic",            "Integrity",       DATA_STRING, "CHECKSUM",
             NULL);
    }

    // Output (simulated) message level deciphering information..
    if (decoder->verbose == 1) {
        decoder_output_bitrowf(decoder, b, XC0324_MESSAGE_BITLEN,
          "Temp was %4.1f <- XC0324:vv row %03d bit %03d",
          temperature, row, bitpos);
    }
    // Output "finished deciphering" reference values for future regression tests.
    if ((decoder->verbose == 3) & (latest_event == 0)) {
        //info from this first successful message is enough
        decoder_output_messagef(decoder,
          "XC0324:vvvv Reference -> Temperature %4.1f C; sensor id %s",
          temperature, id);
    }
    return 1; // Message successfully decoded
}
コード例 #19
0
/*!
 * @brief Transmit a packet via SSL _and_ destroy it.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the \c Packet that is to be sent.
 * @param completion Pointer to the completion routines to process.
 * @return An indication of the result of processing the transmission request.
 * @remark This uses an SSL-encrypted TCP channel, and does not imply the use of HTTPS.
 */
DWORD packet_transmit_via_ssl(Remote* remote, Packet* packet, PacketRequestCompletion* completion)
{
	CryptoContext* crypto;
	Tlv requestId;
	DWORD res;
	DWORD idx;
	TcpTransportContext* ctx = (TcpTransportContext*)remote->transport->ctx;

	lock_acquire(remote->lock);

	// If the packet does not already have a request identifier, create one for it
	if (packet_get_tlv_string(packet, TLV_TYPE_REQUEST_ID, &requestId) != ERROR_SUCCESS)
	{
		DWORD index;
		CHAR rid[32];

		rid[sizeof(rid)-1] = 0;

		for (index = 0; index < sizeof(rid)-1; index++)
		{
			rid[index] = (rand() % 0x5e) + 0x21;
		}

		packet_add_tlv_string(packet, TLV_TYPE_REQUEST_ID, rid);
	}

	do
	{
		// If a completion routine was supplied and the packet has a request
		// identifier, insert the completion routine into the list
		if ((completion) &&
			(packet_get_tlv_string(packet, TLV_TYPE_REQUEST_ID,
			&requestId) == ERROR_SUCCESS))
		{
			packet_add_completion_handler((LPCSTR)requestId.buffer, completion);
		}

		// If the endpoint has a cipher established and this is not a plaintext
		// packet, we encrypt
		if ((crypto = remote_get_cipher(remote)) &&
			(packet_get_type(packet) != PACKET_TLV_TYPE_PLAIN_REQUEST) &&
			(packet_get_type(packet) != PACKET_TLV_TYPE_PLAIN_RESPONSE))
		{
			ULONG origPayloadLength = packet->payloadLength;
			PUCHAR origPayload = packet->payload;

			// Encrypt
			if ((res = crypto->handlers.encrypt(crypto, packet->payload,
				packet->payloadLength, &packet->payload,
				&packet->payloadLength)) !=
				ERROR_SUCCESS)
			{
				SetLastError(res);
				break;
			}

			// Destroy the original payload as we no longer need it
			free(origPayload);

			// Update the header length
			packet->header.length = htonl(packet->payloadLength + sizeof(TlvHeader));
		}

		dprintf("[PACKET] New xor key for sending");
		packet->header.xor_key = rand_xor_key();
		// before transmission, xor the whole lot, starting with the body
		xor_bytes(packet->header.xor_key, (LPBYTE)packet->payload, packet->payloadLength);
		// then the header
		xor_bytes(packet->header.xor_key, (LPBYTE)&packet->header.length, 8);
		// be sure to switch the xor header before writing
		packet->header.xor_key = htonl(packet->header.xor_key);

		idx = 0;
		while (idx < sizeof(packet->header))
		{
			// Transmit the packet's header (length, type)
			res = SSL_write(
				ctx->ssl,
				(LPCSTR)(&packet->header) + idx,
				sizeof(packet->header) - idx
				);

			if (res <= 0)
			{
				dprintf("[PACKET] transmit header failed with return %d at index %d\n", res, idx);
				break;
			}
			idx += res;
		}

		if (res < 0)
		{
			break;
		}

		idx = 0;
		while (idx < packet->payloadLength)
		{
			// Transmit the packet's payload (length, type)
			res = SSL_write(
				ctx->ssl,
				packet->payload + idx,
				packet->payloadLength - idx
				);

			if (res < 0)
			{
				break;
			}

			idx += res;
		}

		if (res < 0)
		{
			dprintf("[PACKET] transmit header failed with return %d at index %d\n", res, idx);
			break;
		}

		SetLastError(ERROR_SUCCESS);
	} while (0);

	res = GetLastError();

	// Destroy the packet
	packet_destroy(packet);

	lock_release(remote->lock);

	return res;
}
コード例 #20
0
/*!
 * @brief Receive a new packet on the given remote endpoint.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to a pointer that will receive the \c Packet data.
 * @return An indication of the result of processing the transmission request.
 */
static DWORD packet_receive_via_ssl(Remote *remote, Packet **packet)
{
	DWORD headerBytes = 0, payloadBytesLeft = 0, res;
	CryptoContext *crypto = NULL;
	Packet *localPacket = NULL;
	PacketHeader header;
	LONG bytesRead;
	BOOL inHeader = TRUE;
	PUCHAR payload = NULL;
	ULONG payloadLength;
	TcpTransportContext* ctx = (TcpTransportContext*)remote->transport->ctx;

	lock_acquire(remote->lock);

	do
	{
		// Read the packet length
		while (inHeader)
		{
			if ((bytesRead = SSL_read(ctx->ssl, ((PUCHAR)&header + headerBytes), sizeof(PacketHeader)-headerBytes)) <= 0)
			{
				if (!bytesRead)
				{
					SetLastError(ERROR_NOT_FOUND);
				}

				if (bytesRead < 0)
				{
					dprintf("[PACKET] receive header failed with error code %d. SSLerror=%d, WSALastError=%d\n", bytesRead, SSL_get_error(ctx->ssl, bytesRead), WSAGetLastError());
					SetLastError(ERROR_NOT_FOUND);
				}

				break;
			}

			headerBytes += bytesRead;

			if (headerBytes != sizeof(PacketHeader))
			{
				continue;
			}

			inHeader = FALSE;
		}

		if (headerBytes != sizeof(PacketHeader))
		{
			break;
		}

		header.xor_key = ntohl(header.xor_key);

		// xor the header data
		xor_bytes(header.xor_key, &header.length, 8);

		// Initialize the header
		header.length = ntohl(header.length);

		// use TlvHeader size here, because the length doesn't include the xor byte
		payloadLength = header.length - sizeof(TlvHeader);
		payloadBytesLeft = payloadLength;

		// Allocate the payload
		if (!(payload = (PUCHAR)malloc(payloadLength)))
		{
			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
			break;
		}

		// Read the payload
		while (payloadBytesLeft > 0)
		{
			if ((bytesRead = SSL_read(ctx->ssl, payload + payloadLength - payloadBytesLeft, payloadBytesLeft)) <= 0)
			{

				if (GetLastError() == WSAEWOULDBLOCK)
				{
					continue;
				}

				if (!bytesRead)
				{
					SetLastError(ERROR_NOT_FOUND);
				}

				if (bytesRead < 0)
				{
					dprintf("[PACKET] receive payload of length %d failed with error code %d. SSLerror=%d\n", payloadLength, bytesRead, SSL_get_error(ctx->ssl, bytesRead));
					SetLastError(ERROR_NOT_FOUND);
				}

				break;
			}

			payloadBytesLeft -= bytesRead;
		}

		// Didn't finish?
		if (payloadBytesLeft)
		{
			break;
		}

		xor_bytes(header.xor_key, payload, payloadLength);

		// Allocate a packet structure
		if (!(localPacket = (Packet *)malloc(sizeof(Packet))))
		{
			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
			break;
		}

		memset(localPacket, 0, sizeof(Packet));

		// If the connection has an established cipher and this packet is not
		// plaintext, decrypt
		if ((crypto = remote_get_cipher(remote)) &&
			(packet_get_type(localPacket) != PACKET_TLV_TYPE_PLAIN_REQUEST) &&
			(packet_get_type(localPacket) != PACKET_TLV_TYPE_PLAIN_RESPONSE))
		{
			ULONG origPayloadLength = payloadLength;
			PUCHAR origPayload = payload;

			// Decrypt
			if ((res = crypto->handlers.decrypt(crypto, payload, payloadLength, &payload, &payloadLength)) != ERROR_SUCCESS)
			{
				SetLastError(res);
				break;
			}

			// We no longer need the encrypted payload
			free(origPayload);
		}

		localPacket->header.length = header.length;
		localPacket->header.type = header.type;
		localPacket->payload = payload;
		localPacket->payloadLength = payloadLength;

		*packet = localPacket;

		SetLastError(ERROR_SUCCESS);

	} while (0);

	res = GetLastError();

	// Cleanup on failure
	if (res != ERROR_SUCCESS)
	{
		if (payload)
		{
			free(payload);
		}
		if (localPacket)
		{
			free(localPacket);
		}
	}

	lock_release(remote->lock);

	return res;
}