26#include <qcbor/qcbor_encode.h>
27#include <qcbor/qcbor_spiffy_decode.h>
41 CHK_AS_BOOL(self != NULL);
42 CHK_AS_BOOL(self->sec_context_id > 0);
43 CHK_AS_BOOL(self->source_eid.handle != NULL);
44 CHK_AS_BOOL(BSLB_SecParamList_size(self->params) < 10000);
47 CHK_AS_BOOL(BSLB_SecResultList_size(self->results) < 10000);
50 CHK_AS_BOOL(uint64_list_size(self->targets) < 10000);
57 BSL_StaticString_t str;
58 BSL_LOG_INFO(
"ASB context id: %lu", self->sec_context_id);
59 for (
size_t index = 0; index < uint64_list_size(self->targets); index++)
61 BSL_LOG_INFO(
"ASB target[%lu]: %lu", index, *uint64_list_get(self->targets, index));
64 for (
size_t index = 0; index < BSLB_SecParamList_size(self->params); index++)
66 BSL_SecParam_t *param = BSLB_SecParamList_get(self->params, index);
70 for (
size_t index = 0; index < BSLB_SecResultList_size(self->results); index++)
72 BSL_SecResult_t *sec_result = BSLB_SecResultList_get(self->results, index);
80 ASSERT_ARG_NONNULL(self);
82 memset(self, 0,
sizeof(*self));
83 BSLB_SecParamList_init(self->params);
84 BSLB_SecResultList_init(self->results);
85 uint64_list_init(self->targets);
90 ASSERT_ARG_NONNULL(self);
91 memset(self, 0,
sizeof(*self));
92 self->sec_context_id = sec_context_id;
93 self->source_eid = source_eid;
94 BSLB_SecParamList_init(self->params);
95 BSLB_SecResultList_init(self->results);
96 uint64_list_init(self->targets);
104 BSLB_SecParamList_clear(self->params);
105 BSLB_SecResultList_clear(self->results);
106 uint64_list_clear(self->targets);
108 memset(self, 0,
sizeof(*self));
113 ASSERT_ARG_NONNULL(self);
114 bool is_empty = (uint64_list_size(self->targets) == 0) && (BSLB_SecResultList_size(self->results) == 0);
122 M_EACH(target_num, self->targets, LIST_OPLIST(uint64_list))
124 if (*target_num == target_block_num)
136 uint64_list_push_back(self->targets, target_block_id);
143 ASSERT_ARG_NONNULL(param);
146 BSLB_SecParamList_push_back(self->params, *param);
153 ASSERT_ARG_NONNULL(result);
156 BSLB_SecResultList_push_back(self->results, *result);
161static size_t BSL_AbsSecBlock_GetResultCnt(
const BSL_AbsSecBlock_t *self, uint64_t target_block_id)
165 size_t match_count = 0;
166 for (
size_t index = 0; index < BSLB_SecResultList_size(self->results); index++)
168 BSL_SecResult_t *result = BSLB_SecResultList_get(self->results, index);
181 size_t things_removed = 0;
185 uint64_list_it_t target_iter;
186 uint64_list_it(target_iter, self->targets);
187 for (
size_t i = 0; i < uint64_list_size(self->targets); i++)
189 uint64_t *curr_target = uint64_list_ref(target_iter);
190 if (*curr_target == target_block_num)
194 uint64_list_next(target_iter);
196 ASSERT_PROPERTY(!uint64_list_end_p(target_iter));
198 uint64_list_remove(self->targets, target_iter);
201 while (BSL_AbsSecBlock_GetResultCnt(self, target_block_num) > 0)
203 BSLB_SecResultList_it_t result_iter;
204 BSLB_SecResultList_it(result_iter, self->results);
206 for (index = 0; index < BSLB_SecResultList_size(self->results); index++)
213 BSLB_SecResultList_next(result_iter);
216 if (!BSLB_SecResultList_end_p(result_iter) && index < BSLB_SecResultList_size(self->results))
218 BSLB_SecResultList_remove(self->results, result_iter);
230 return (
int)things_removed;
235 CHK_ARG_NONNULL(allocated_target.
ptr);
236 CHK_ARG_EXPR(allocated_target.
len > 0);
240 QCBOREncodeContext encoder;
241 UsefulBuf allocated_buf = { .ptr = allocated_target.
ptr, .len = allocated_target.
len };
242 QCBOREncode_Init(&encoder, allocated_buf);
245 QCBOREncode_OpenArray(&encoder);
246 for (
size_t target_index = 0; target_index < uint64_list_size(self->targets); target_index++)
248 QCBOREncode_AddUInt64(&encoder, *uint64_list_get(self->targets, target_index));
250 QCBOREncode_CloseArray(&encoder);
254 QCBOREncode_AddUInt64(&encoder, self->sec_context_id);
259 uint64_t flags = BSLB_SecParamList_size(self->params) > 0 ? true :
false;
260 QCBOREncode_AddUInt64(&encoder, flags);
266 QCBOREncode_OpenArray(&encoder);
267 for (
size_t param_index = 0; param_index < BSLB_SecParamList_size(self->params); param_index++)
269 const BSL_SecParam_t *param = BSLB_SecParamList_cget(self->params, param_index);
270 QCBOREncode_OpenArray(&encoder);
271 QCBOREncode_AddUInt64(&encoder, param->
param_id);
280 UsefulBufC bytestr_buf = { .ptr = bytestr.
ptr, .len = bytestr.
len };
281 QCBOREncode_AddBytes(&encoder, bytestr_buf);
283 QCBOREncode_CloseArray(&encoder);
285 QCBOREncode_CloseArray(&encoder);
290 QCBOREncode_OpenArray(&encoder);
291 for (
size_t target_index = 0; target_index < uint64_list_size(self->targets); target_index++)
293 QCBOREncode_OpenArray(&encoder);
294 const uint64_t *target_block_num = uint64_list_cget(self->targets, target_index);
295 for (
size_t result_index = 0; result_index < BSLB_SecResultList_size(self->results); result_index++)
297 const BSL_SecResult_t *sec_result = BSLB_SecResultList_cget(self->results, result_index);
302 QCBOREncode_OpenArray(&encoder);
303 QCBOREncode_AddUInt64(&encoder, sec_result->
result_id);
304 UsefulBufC result_buf = { .ptr = sec_result->
_bytes, .len = sec_result->
_bytelen };
305 QCBOREncode_AddBytes(&encoder, result_buf);
306 QCBOREncode_CloseArray(&encoder);
308 QCBOREncode_CloseArray(&encoder);
311 QCBOREncode_CloseArray(&encoder);
314 UsefulBufC output_buf;
315 QCBORError qcbor_err = QCBOREncode_Finish(&encoder, &output_buf);
316 if (qcbor_err != QCBOR_SUCCESS)
318 BSL_LOG_ERR(
"Encoding ASB into BTSD failed: %s", qcbor_err_to_str(qcbor_err));
321 return (
int)output_buf.len;
326 CHK_ARG_NONNULL(self);
327 CHK_ARG_EXPR(encoded_cbor.
len > 0);
328 CHK_ARG_EXPR(encoded_cbor.
ptr != NULL);
332 QCBORDecodeContext asbdec;
333 UsefulBufC useful_encoded_cbor = { .ptr = encoded_cbor.
ptr, .len = encoded_cbor.
len };
334 QCBORDecode_Init(&asbdec, useful_encoded_cbor, QCBOR_DECODE_MODE_NORMAL);
338 QCBORDecode_EnterArray(&asbdec, NULL);
339 while (QCBOR_SUCCESS == QCBORDecode_PeekNext(&asbdec, &asbitem))
342 uint64_t tgt_num = 0;
343 QCBORDecode_GetUInt64(&asbdec, &tgt_num);
345 uint64_list_push_back(self->targets, tgt_num);
348 QCBORDecode_ExitArray(&asbdec);
352 QCBORDecode_GetInt64(&asbdec, &ctx_id);
353 if ((ctx_id < INT16_MIN) || (ctx_id > INT16_MAX))
359 self->sec_context_id = ctx_id;
365 QCBORDecode_GetUInt64(&asbdec, &flags);
376 QCBORDecode_EnterArray(&asbdec, NULL);
377 while (QCBOR_SUCCESS == QCBORDecode_PeekNext(&asbdec, &asbitem))
380 QCBORDecode_EnterArray(&asbdec, NULL);
382 uint64_t item_id = 0;
383 QCBORDecode_GetUInt64(&asbdec, &item_id);
385 const size_t item_begin = QCBORDecode_Tell(&asbdec);
387 QCBORDecode_PeekNext(&asbdec, &asbitem);
388 if (asbitem.uDataType == QCBOR_TYPE_INT64)
390 uint64_t param_u64_value = 0;
391 QCBORDecode_GetUInt64(&asbdec, ¶m_u64_value);
392 BSL_LOG_DEBUG(
"ASB: Parsed Param[%lu] = %lu", item_id, param_u64_value);
395 BSLB_SecParamList_push_back(self->params, param);
397 else if (asbitem.uDataType == QCBOR_TYPE_BYTE_STRING)
399 UsefulBufC target_buf;
400 QCBORDecode_GetByteString(&asbdec, &target_buf);
401 BSL_LOG_DEBUG(
"ASB: Parsed Param[%lu] (ByteStr) = %lu bytes", item_id, target_buf.len);
403 BSL_Data_t data_view = { .
owned = 0, .ptr = (uint8_t *)target_buf.ptr, .len = target_buf.len };
405 BSLB_SecParamList_push_back(self->params, param);
415 const size_t item_end = QCBORDecode_Tell(&asbdec);
416 BSL_LOG_DEBUG(
"param %" PRIu64
" between %" PRId64
" and %" PRId64, item_id, item_begin, item_end);
418 QCBORDecode_ExitArray(&asbdec);
420 QCBORDecode_ExitArray(&asbdec);
423 QCBORDecode_EnterArray(&asbdec, NULL);
424 size_t result_index = 0;
425 while (QCBOR_SUCCESS == QCBORDecode_PeekNext(&asbdec, &asbitem))
428 size_t target_id = 0;
429 for (
size_t i = 0; i < uint64_list_size(self->targets); i++)
431 if (i == result_index)
433 target_id = *uint64_list_get(self->targets, i);
439 BSL_LOG_DEBUG(
"Parsing ASB results for target[index=%lu, block#=%lu]", result_index, target_id);
442 QCBORDecode_EnterArray(&asbdec, NULL);
443 while (QCBOR_SUCCESS == QCBORDecode_PeekNext(&asbdec, &asbitem))
446 QCBORDecode_EnterArray(&asbdec, NULL);
448 uint64_t item_id = 0;
449 QCBORDecode_GetUInt64(&asbdec, &item_id);
451 const size_t item_begin = QCBORDecode_Tell(&asbdec);
453 QCBORError is_ok = QCBORDecode_PeekNext(&asbdec, &asbitem);
454 CHK_PROPERTY(is_ok == QCBOR_SUCCESS);
456 if (asbitem.uDataType == QCBOR_TYPE_BYTE_STRING)
459 QCBORDecode_GetByteString(&asbdec, &buf);
460 BSL_Data_t bufdata = { .
owned = 0, .ptr = (uint8_t *)buf.ptr, .len = buf.len };
462 int result_code =
BSL_SecResult_Init(&result, item_id, self->sec_context_id, target_id, bufdata);
463 ASSERT_PROPERTY(result_code == 0);
466 BSLB_SecResultList_push_back(self->results, result);
474 const size_t item_end = QCBORDecode_Tell(&asbdec);
475 BSL_LOG_DEBUG(
"result %" PRIu64
" between %" PRId64
" and %" PRId64, item_id, item_begin, item_end);
477 QCBORDecode_ExitArray(&asbdec);
479 QCBORDecode_ExitArray(&asbdec);
481 QCBORDecode_ExitArray(&asbdec);
483 QCBORError err = QCBORDecode_Finish(&asbdec);
484 if (err != QCBOR_SUCCESS)
486 BSL_LOG_WARNING(
"ASB decoding error %" PRIu32
" (%s)", err, qcbor_err_to_str(err));
Concrete implementation of ASB and its functionality.
Single entry-point include file for all of the BPSec Lib (BSL) frontend API.
#define BSL_LOG_DEBUG(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool BSL_AbsSecBlock_ContainsTarget(const BSL_AbsSecBlock_t *self, uint64_t target_block_num)
Returns true if a given ASB contains the given block number as a security target.
void BSL_AbsSecBlock_Deinit(BSL_AbsSecBlock_t *self)
Deinitializes and clears this ASB, clearing and releasing any owned memory.
void BSL_AbsSecBlock_AddResult(BSL_AbsSecBlock_t *self, const BSL_SecResult_t *result)
Add a security result to this security block (does NOT copy)
#define BSL_LOG_INFO(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
struct BSL_AbsSecBlock_s BSL_AbsSecBlock_t
Forward declaration of BSL_AbsSecBlock_t.
#define BSL_LOG_WARNING(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void BSL_AbsSecBlock_AddTarget(BSL_AbsSecBlock_t *self, uint64_t target_block_id)
Adds a given block ID as a security target covered by this ASB.
int BSL_AbsSecBlock_StripResults(BSL_AbsSecBlock_t *self, uint64_t target_block_num)
Remove security parameters and results found in outcome from this ASB.
void BSL_AbsSecBlock_Init(BSL_AbsSecBlock_t *self, uint64_t sec_context_id, BSL_HostEID_t source_eid)
Populate a pre-allocated Absract Security Block.
void BSL_AbsSecBlock_InitEmpty(BSL_AbsSecBlock_t *self)
Initialize a pre-allocated ASB with no contents.
int BSL_AbsSecBlock_DecodeFromCBOR(BSL_AbsSecBlock_t *self, BSL_Data_t encoded_cbor)
Decodes and populates this ASB from a CBOR string.
bool BSL_AbsSecBlock_IsEmpty(const BSL_AbsSecBlock_t *self)
Returns true if this ASB contains nothing (i.e., no tarets, params and results)
size_t BSL_AbsSecBlock_Sizeof(void)
Returns the size of the AbsSecBlock struct in bytes.
int BSL_AbsSecBlock_EncodeToCBOR(const BSL_AbsSecBlock_t *self, BSL_Data_t allocated_target)
Encodes this ASB into a CBOR string into the space pre-allocated indicated by the argument.
void BSL_AbsSecBlock_AddParam(BSL_AbsSecBlock_t *self, const BSL_SecParam_t *param)
Add a security parameter to this security block (does NOT copy)
#define BSL_LOG_ERR(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool BSL_AbsSecBlock_IsConsistent(const BSL_AbsSecBlock_t *self)
Checks internal consistency and sanity of this structure.
@ BSL_ERR_PROPERTY_CHECK_FAILED
The BSL of a structure within it is not in a valid state.
@ BSL_ERR_ENCODING
CBOR encoding failure.
@ BSL_ERR_DECODING
CBOR decoding failure.
@ BSL_SUCCESS
Placeholder for non-error code.
void BSL_AbsSecBlock_Print(const BSL_AbsSecBlock_t *self)
Prints to LOG INFO.
int BSL_HostEID_DecodeFromCBOR(BSL_HostEID_t *eid, void *decoder)
Load an EID from CBOR.
int BSL_HostEID_EncodeToCBOR(const BSL_HostEID_t *eid, void *user_data)
Encode a EID into a CBOR sequence.
int BSL_HostEID_Init(BSL_HostEID_t *eid)
Initialize an abstract EID.
void BSL_HostEID_Deinit(BSL_HostEID_t *eid)
De-initialize an abstract EID.
uint8_t * BSL_Log_DumpAsHexString(uint8_t *dstbuf, size_t dstlen, const uint8_t *srcbuf, size_t srclen)
NOLINTEND.
int BSL_SecParam_IsInt64(const BSL_SecParam_t *self)
Returns true when the value type is an integer.
int BSL_SecParam_GetAsBytestr(const BSL_SecParam_t *self, BSL_Data_t *result)
Retrieve bytestring value of result when security parameter type is bytestring.
int BSL_SecParam_InitInt64(BSL_SecParam_t *self, uint64_t param_id, uint64_t value)
Initialize as a parameter containing an integer as a value.
int BSL_SecParam_InitBytestr(BSL_SecParam_t *self, uint64_t param_id, BSL_Data_t value)
Initialize as a parameter containing a bytestring.
uint64_t BSL_SecParam_GetAsUInt64(const BSL_SecParam_t *self)
Retrieve integer value of result when this result type is integer.
int BSL_SecResult_Init(BSL_SecResult_t *self, uint64_t result_id, uint64_t context_id, uint64_t target_block_num, BSL_Data_t content)
Populate a pre-allocated SecResult.
Heap data storage and views.
size_t len
Size of the data buffer.
BSL_DataPtr_t ptr
Pointer to the front of the buffer.
bool owned
True if this data is a copy.
Opaque pointer to BPA-specific Endpoint ID storage.
uint64_t param_id
Parameter ID.
uint64_t _uint_value
Private. When an integer, this field is populated with the correct value.
uint8_t _bytes[BSL_DEFAULT_BYTESTR_LEN+1]
Result as byte array, up to a given maximum.
uint64_t target_block_num
Target block id, put in here for convenience.
uint64_t result_id
Result ID, which is context depdendent, based on security context.
size_t _bytelen
Length of data (in bytes) of the contained bytestring. Always less than BSL_DEFAULT_BYTESTR_LEN.