Exemple #1
0
/* check if nonce-count nc w/ index i is expected/valid and if so it 
 * updated the stored nonce-count
 * returns: 0 - ok, < 0 some error:
 * NC_INV_POOL      (pool number is invalid/corrupted)
 * NC_ID_OVERFLOW (crt_id has overflowed with partition size since the
 *                   id was generated)
 * NC_TOO_BIG       (nc value got too big and cannot be held anymore)
 * NC_REPLAY        (nc value is <= the current stored one)
 */
enum nc_check_ret nc_check_val(nid_t id, unsigned pool, unsigned int nc)
{
	unsigned int i;
	unsigned n, r;
	unsigned int v, crt_nc, new_v;
	
	if (unlikely(pool>=nid_pool_no))
		return NC_INV_POOL;
	if (unlikely(nc_id_check_overflow(id, pool)))
		return NC_ID_OVERFLOW;
	if (unlikely(nc>=(1U<<(sizeof(nc_t)*8))))
		return NC_TOO_BIG;
	n=get_nc_array_raw_idx(id, pool); /* n-th nc_t */
	i=get_nc_array_uint_idx(n);  /* aray index i, corresponding to n */
	r=get_nc_int_pos(n); /* byte/short inside the uint corresponding to n */
	do{
		v=atomic_get_int(&nc_array[i]);
		/* get current (stored) nc value */
		crt_nc=(v>>(r*8)) & ((1U<<(sizeof(nc_t)*8))-1);
		if (crt_nc>=nc)
			return NC_REPLAY;
		/* set corresponding array cell byte/short to new nc */
		new_v=(v & ~(((1U<<(sizeof(nc_t)*8))-1)<< (r*8)) )|
				(nc << (r*8));
	}while(atomic_cmpxchg_int((int*)&nc_array[i], v, new_v)!=v);
	return 0;
}
Exemple #2
0
/* check if nonce w/ index i is expected/valid and if so marked it "seen"
 * returns: 0 - ok, < 0 some error:
 * OTN_INV_POOL      (pool number is invalid/corrupted)
 * OTN_ID_OVERFLOW   (crt_id has overflowed with partition size since the
 *                    id was generated)
 * OTN_REPLAY        (nonce id seen before => replay )
 */
enum otn_check_ret otn_check_id(nid_t id, unsigned pool)
{
	unsigned int i;
	unsigned n, b;
	otn_cell_t v, b_mask;

	if (unlikely(pool>=nid_pool_no))
		return OTN_INV_POOL;
	if (unlikely(otn_id_check_overflow(id, pool)))
		return OTN_ID_OVERFLOW;
	n=get_otn_array_bit_idx(id, pool); /* n-th bit */
	i=get_otn_array_cell_idx(n);    /* aray index i, corresponding to n */
	b=get_otn_cell_bit(n);          /* bit pos corresponding to n */
	b_mask= (otn_cell_t)1<<b;

#ifdef OTN_CELL_T_LONG
	v=atomic_get_long(&oth_array[i]);
	if (unlikely(v & b_mask))
		return OTN_REPLAY;
	atomic_or_long((long*)&otn_array[i],  b_mask);
#else
	v=atomic_get_int(&otn_array[i]);
	if (unlikely(v & b_mask))
		return OTN_REPLAY;
	atomic_or_int((int*)&otn_array[i],  b_mask);
#endif /* OTN_CELL_T_LONG */
	return 0;
}
Exemple #3
0
/* re-init the stored nc for nonce id in pool p */
nid_t nc_new(nid_t id, unsigned char p)
{
	unsigned int i;
	unsigned  n, r;
	unsigned int v, new_v;
	
	n=get_nc_array_raw_idx(id, p); /* n-th nc_t */
	i=get_nc_array_uint_idx(n);  /* aray index i, corresponding to n */
	r=get_nc_int_pos(n);  /* byte/short inside the uint corresponding to n */
	/* reset corresponding value to 0 */
	do{
		v=atomic_get_int(&nc_array[i]);
		/* new_value = old_int with the corresponding byte or short zeroed*/
		new_v=v & ~(((1<<(sizeof(nc_t)*8))-1)<< (r*8));
	}while(atomic_cmpxchg_int((int*)&nc_array[i], v, new_v)!=v);
	return id;
}