Example #1
0
/** Encrypts a packet and adds the common method header */
static bool method_encrypt(UNUSED fastd_peer_t *peer, fastd_method_session_state_t *session, fastd_buffer_t *out, fastd_buffer_t in) {
    size_t tail_len = alignto(in.len, sizeof(fastd_block128_t))-in.len;
    *out = fastd_buffer_alloc(in.len, alignto(COMMON_HEADBYTES, 16), sizeof(fastd_block128_t)+tail_len);

    if (tail_len)
        memset(in.data+in.len, 0, tail_len);

    uint8_t nonce[session->method->cipher_info->iv_length ?: 1] __attribute__((aligned(8)));
    fastd_method_expand_nonce(nonce, session->common.send_nonce, sizeof(nonce));

    int n_blocks = block_count(in.len, sizeof(fastd_block128_t));

    fastd_block128_t *inblocks = in.data;
    fastd_block128_t *outblocks = out->data;

    bool ok = session->cipher->crypt(session->cipher_state, outblocks, inblocks, n_blocks*sizeof(fastd_block128_t), nonce);

    if (!ok) {
        fastd_buffer_free(*out);
        return false;
    }

    fastd_buffer_free(in);

    fastd_method_put_common_header(out, session->common.send_nonce, 0);
    fastd_method_increment_nonce(&session->common);

    return true;
}
Example #2
0
/** Verifies and decrypts a packet */
static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *session, fastd_buffer_t *out, fastd_buffer_t in, bool *reordered) {
	if (in.len < COMMON_HEADBYTES+sizeof(fastd_block128_t))
		return false;

	if (!method_session_is_valid(session))
		return false;

	uint8_t in_nonce[COMMON_NONCEBYTES];
	uint8_t flags;
	int64_t age;
	if (!fastd_method_handle_common_header(&session->common, &in, in_nonce, &flags, &age))
		return false;

	if (flags)
		return false;

	uint8_t nonce[session->method->cipher_info->iv_length] __attribute__((aligned(8)));
	fastd_method_expand_nonce(nonce, in_nonce, sizeof(nonce));

	size_t tail_len = alignto(in.len, sizeof(fastd_block128_t))-in.len;
	*out = fastd_buffer_alloc(in.len, 0, tail_len);

	int n_blocks = block_count(in.len, sizeof(fastd_block128_t));

	fastd_block128_t *inblocks = in.data;
	fastd_block128_t *outblocks = out->data;
	fastd_block128_t tag;

	bool ok = session->cipher->crypt(session->cipher_state, outblocks, inblocks, n_blocks*sizeof(fastd_block128_t), nonce);

	if (ok) {
		if (tail_len)
			memset(in.data+in.len, 0, tail_len);

		put_size(&inblocks[n_blocks], in.len-sizeof(fastd_block128_t));

		ok = session->ghash->digest(session->ghash_state, &tag, inblocks+1, n_blocks*sizeof(fastd_block128_t));
	}

	if (!ok || !block_equal(&tag, &outblocks[0])) {
		fastd_buffer_free(*out);
		return false;
	}

	fastd_buffer_free(in);

	fastd_buffer_push_head(out, sizeof(fastd_block128_t));

	fastd_tristate_t reorder_check = fastd_method_reorder_check(peer, &session->common, in_nonce, age);
	if (reorder_check.set) {
		*reordered = reorder_check.state;
	}
	else {
		fastd_buffer_free(*out);
		*out = fastd_buffer_alloc(0, 0, 0);
	}

	return true;
}
Example #3
0
static int
bin_listend(Generator* generator, Symbol* tsym, void* liststate, ListClass lc, int uid, size_t count, Bytebuffer* buf, ...)
{
    if(lc == LISTCOMPOUND) {
        int offsetbase = *((int*)liststate);
        /* Pad out the whole instance */
	alignto(tsym->typ.cmpdalign,buf,offsetbase);		
    }
    return 1;
}
Example #4
0
static int
bin_list(Generator* generator, Symbol* tsym, void* liststate, ListClass lc, int uid, size_t count, Bytebuffer* buf, ...)
{
    if(lc == LISTCOMPOUND) {
        int offsetbase = *((int*)liststate);
        /* Pad for the alignment */
	alignto(tsym->typ.alignment,buf,offsetbase);		
    }
    return 1;
}
Example #5
0
/** Encrypts and authenticates a packet */
static bool method_encrypt(UNUSED fastd_peer_t *peer, fastd_method_session_state_t *session, fastd_buffer_t *out, fastd_buffer_t in) {
	size_t tail_len = in.len ? alignto(in.len, 2 * sizeof(fastd_block128_t))-in.len : (2 * sizeof(fastd_block128_t));

	fastd_buffer_pull_head_zero(&in, sizeof(fastd_block128_t));

	*out = fastd_buffer_alloc(in.len, alignto(COMMON_HEADBYTES, 16), tail_len);

	uint8_t nonce[session->method->cipher_info->iv_length] __attribute__((aligned(8)));
	fastd_method_expand_nonce(nonce, session->common.send_nonce, sizeof(nonce));

	int n_blocks = block_count(in.len, sizeof(fastd_block128_t));

	fastd_block128_t *inblocks = in.data;
	fastd_block128_t *outblocks = out->data;
	fastd_block128_t tag;

	bool ok = session->cipher->crypt(session->cipher_state, outblocks, inblocks, n_blocks*sizeof(fastd_block128_t), nonce);

	if (ok) {
		if (tail_len)
			memset(out->data+out->len, 0, tail_len);

		ok = session->uhash->digest(session->uhash_state, &tag, outblocks+1, out->len - sizeof(fastd_block128_t));
	}

	if (!ok) {
		fastd_buffer_free(*out);
		return false;
	}

	xor_a(&outblocks[0], &tag);

	fastd_buffer_free(in);

	fastd_method_put_common_header(out, session->common.send_nonce, 0);
	fastd_method_increment_nonce(&session->common);

	return true;
}
Example #6
0
extern void *nalloc(size_t n) {
	size_t base;
	Block *ulp;
        n = alignto(n, sizeof (ALIGN_T));
	ulp = ul;
	if (ulp != NULL && n + (base = ulp->used) < ulp->size) {
		ulp->used = base + n;
		return &ulp->mem[base];
	} else {
		getblock(n); /* assert(ul->used) == 0 */
		(ulp = ul)->used = n;
		return &ulp->mem[0];
	}
}
Example #7
0
static void getblock(size_t n) {
	Block *r, *p;
	for (r = fl, p = NULL; r != NULL; p = r, r = r->n)
		if (n <= r->size)
			break;	/* look for a block which fits the request */
	if (r != NULL) {	/* if one is found, take it off the free list */	
		if (p != NULL)
			p->n = r->n;
		else
			fl = r->n;
	} else {		/* else allocate a new block */
		r = enew(Block);
		r->mem = ealloc(r->size = alignto(n, BLOCKSIZE));
	}
	r->used = 0;
	r->n = ul;
	ul = r;
}
Example #8
0
/* Used for compound instances */
static void
genbin_compound(Symbol* tsym, Datasrc* datasrc, Datalist* fillsrc, Bytebuffer* memory)
{
    int i;
    int base = bblength(memory);
    if(!issublist(datasrc)) {
        semerror(srcline(datasrc),"Compound data must be enclosed in {..}");
    }
    /* Use this datasrc list to get values for compound fields */
    srcpush(datasrc);
    for(i=0;i<listlength(tsym->subnodes);i++) {
        Symbol* field = (Symbol*)listget(tsym->subnodes,i);
	if(!srcmore(datasrc)) { /* generate a fill value*/
	    Datalist* fillsrc = getfiller(tsym);
	    genbin_data(field,datasrc,fillsrc,memory);
	} else
	    genbin_data(field,datasrc,NULL,memory);
    }
    srcpop(datasrc);
    /* Re: github issue 323: we may need to pad the end of the structure
       to make its size be a multiple of the largest alignment.
    */
    alignto(tsym->cmpdalignment,buf,base);
}