29#include <qcbor/qcbor_encode.h>
30#include <qcbor/qcbor_spiffy_decode.h>
63size_t BSLX_Bytestr_GetCapacity(
void)
65 return BSL_DEFAULT_BYTESTR_LEN;
70 BSL_Data_t result = { .
owned =
false, .len = self->bytelen, .ptr = self->_bytes };
80 ssize_t crypto_sha_variant = -1;
81 if (rfc9173_sha_variant == RFC9173_BIB_SHA_HMAC512)
83 crypto_sha_variant = BSL_CRYPTO_SHA_512;
85 else if (rfc9173_sha_variant == RFC9173_BIB_SHA_HMAC384)
87 crypto_sha_variant = BSL_CRYPTO_SHA_384;
89 else if (rfc9173_sha_variant == RFC9173_BIB_SHA_HMAC256)
91 crypto_sha_variant = BSL_CRYPTO_SHA_256;
95 BSL_LOG_ERR(
"Unknown RFC9173 SHA variant index: %lu", rfc9173_sha_variant);
98 BSL_LOG_DEBUG(
"Mapping RFC9173 SHA Variant %lu -> %ld", rfc9173_sha_variant, crypto_sha_variant);
99 return crypto_sha_variant;
109 assert(self != NULL);
110 assert(sec_oper != NULL);
111 memset(self, 0,
sizeof(*self));
112 self->sha_variant = -1;
113 self->integrity_scope_flags = -1;
121 uint64_t int_val = -1;
130 self->key_id = int_val;
136 BSL_Data_t bytestr_data = BSLX_Bytestr_AsData(&self->override_key);
138 self->override_key.bytelen = bytestr_data.
len;
140 else if (param_id == RFC9173_BIB_PARAMID_SHA_VARIANT)
143 self->sha_variant = int_val;
145 else if (param_id == RFC9173_BIB_PARAMID_INTEG_SCOPE_FLAG)
148 self->integrity_scope_flags = int_val;
150 else if (param_id == RFC9173_BIB_PARAMID_WRAPPED_KEY)
153 BSL_Data_t bytestr_data = BSLX_Bytestr_AsData(&self->wrapped_key);
155 self->wrapped_key.bytelen = bytestr_data.
len;
164 if (self->sha_variant < 0)
167 BSL_LOG_DEBUG(
"No SHA Variant set, defaulting to SHA_HMAC384");
168 self->sha_variant = RFC9173_BIB_SHA_HMAC384;
171 if (self->sha_variant < 0)
176 if (self->integrity_scope_flags < 0)
179 BSL_LOG_DEBUG(
"No scope flag set, defaulting to everything (0x07)");
180 self->integrity_scope_flags = 0x07;
190 assert(self != NULL);
191 assert(ippt_space.
len > 0);
192 assert(ippt_space.
ptr != NULL);
195 QCBOREncodeContext encoder;
196 QCBORError cbor_err = QCBOR_ERR_UNSUPPORTED;
197 UsefulBuf result_ub = { .ptr = ippt_space.
ptr, ippt_space.
len };
198 QCBOREncode_Init(&encoder, result_ub);
199 QCBOREncode_AddInt64(&encoder, self->integrity_scope_flags);
204 if (self->integrity_scope_flags & RFC9173_BIB_INTEGSCOPEFLAG_INC_PRIM)
206 UsefulBufC prim_encoded = { .ptr = self->primary_block.cbor,
207 .len = self->primary_block.cbor_len };
208 QCBOREncode_AddEncoded(&encoder, prim_encoded);
210 if (self->integrity_scope_flags & RFC9173_BIB_INTEGSCOPEFLAG_INC_TARGET_HDR)
212 BSLX_EncodeHeader(&self->target_block, &encoder);
216 if (self->integrity_scope_flags & RFC9173_BIB_INTEGSCOPEFLAG_INC_SEC_HDR)
218 BSLX_EncodeHeader(&self->sec_block, &encoder);
221 const uint8_t *target_cbor = self->primary_block.cbor;
222 size_t target_cbor_len = self->primary_block.cbor_len;
226 target_cbor = self->target_block.
btsd;
227 target_cbor_len = self->target_block.
btsd_len;
229 UsefulBufC target_blk_btsd = { .ptr = target_cbor, .len = target_cbor_len };
230 QCBOREncode_AddBytes(&encoder, target_blk_btsd);
231 UsefulBufC ippt_result;
232 cbor_err = QCBOREncode_Finish(&encoder, &ippt_result);
233 if (cbor_err != QCBOR_SUCCESS)
235 BSL_LOG_ERR(
"CBOR encoding IPPT failed, code=%" PRIu32
" (%s)", cbor_err, qcbor_err_to_str(cbor_err));
239 return (
int)(ippt_result.len);
253 CHK_ARG_NONNULL(self);
258 if ((res =
BSL_AuthCtx_Init(&hmac_ctx, self->key_id, self->sha_variant)) != 0)
260 BSL_LOG_ERR(
"bsl_hmac_ctx_init failed with code %d", res);
265 BSL_LOG_ERR(
"bsl_hmac_ctx_input_data_buffer failed with code %d", res);
269 void *hmac_result_ptr = (
void *)&self->hmac_result_val._bytes[0];
273 BSL_LOG_ERR(
"bsl_hmac_ctx_finalize failed with code %d", res);
276 self->hmac_result_val.bytelen = hmaclen;
280 BSL_LOG_ERR(
"bsl_hmac_ctx_deinit failed with code %d", res);
288 BSL_LOG_ERR(
"%s failed bsl_crypto code=%ld", __func__, res);
295 CHK_ARG_NONNULL(lib);
296 CHK_ARG_NONNULL(bundle);
297 CHK_ARG_NONNULL(sec_oper);
298 CHK_ARG_NONNULL(sec_outcome);
310 scratch.buffer = scratch_buffer.
ptr;
311 scratch.size = scratch_buffer.
len;
312 scratch.position = 1;
326 if (target_blk_num > 0)
352 assert(ippt_len > 0);
353 ippt_space.
len = (size_t)ippt_len;
370 BSL_SecOutcome_AppendParam(sec_outcome, dst_param);
375 BSL_SecResult_Init(bib_result, RFC9173_BIB_RESULTID_HMAC, RFC9173_CONTEXTID_BIB_HMAC_SHA2,
377 BSL_SecOutcome_AppendResult(sec_outcome, bib_result);
int BSLX_BIB_InitFromSecOper(BSLX_BIB_t *self, const BSL_SecOper_t *sec_oper)
Populate the BIB parameters convenience struct from the security operation struct.
int BSLX_BIB_GenHMAC(BSLX_BIB_t *self, BSL_Data_t ippt_data)
Performs the actual HMAC over the given IPPT, placing the result in hmac_result.
int BSLX_BIB_GenIPPT(BSLX_BIB_t *self, BSL_Data_t ippt_space)
Computes the Integrity-Protected Plaintext (IPPT) for a canonical bundle block (non-primary)
static ssize_t map_rfc9173_sha_variant_to_crypto(size_t rfc9173_sha_variant)
Provides the mapping from the security-context-specific ID defined in RFC9173 to the local ID of the ...
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...
@ BSL_SECPARAM_TYPE_INT_KEY_ID
Used to pass in a key id found in the key registry.
@ BSL_SECPARAM_TYPE_INT_FIXED_KEY
Used by tests to pass in a specific key bytestring.
#define BSL_LOG_WARNING(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
#define BSL_LOG_ERR(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
@ 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_SECURITY_CONTEXT_FAILED
Security Context errors start at 200.
@ BSL_ERR_INSUFFICIENT_SPACE
Insufficient space to complete.
@ BSL_ERR_SECURITY_OPERATION_FAILED
Security operation failed (e.g., BIB did not have enough parameters)
@ BSL_SUCCESS
Placeholder for non-error code.
@ BSL_ERR_FAILURE
Uncategorized failed (prefer to avoid)
int BSL_AuthCtx_Finalize(BSL_AuthCtx_t *hmac_ctx, void **hmac, size_t *hmac_len)
Finalize HMAC tag.
int BSL_AuthCtx_Init(BSL_AuthCtx_t *hmac_ctx, uint64_t keyid, BSL_CryptoCipherSHAVariant_e sha_var)
Initialize HMAC context resources and set private key and SHA variant.
int BSL_AuthCtx_DigestBuffer(BSL_AuthCtx_t *hmac_ctx, const void *data, size_t data_len)
Input data to HMAC sign to context.
int BSL_AuthCtx_Deinit(BSL_AuthCtx_t *hmac_ctx)
Deinitialize HMAC context resources.
Abstract interface for crypto processing.
void * BSLX_ScratchSpace_take(BSLX_ScratchSpace_t *scratch, size_t len)
This means "give me len bytes from the scratch space and increment a counter." This is a convenience ...
Header for the implementation of an example default security context (RFC 9173).
Contains functions only used internally, however, test utilities can include this to unit test them.
int BSL_BundleCtx_GetBlockMetadata(const BSL_BundleRef_t *bundle, uint64_t block_num, BSL_CanonicalBlock_t *result_block)
Returns information about the bundle Canonical block.
int BSL_BundleCtx_GetBundleMetadata(const BSL_BundleRef_t *bundle, BSL_PrimaryBlock_t *result_primary_block)
Calls the host interface to get a bundle primary block information.abort.
uint64_t BSL_SecOper_GetSecurityBlockNum(const BSL_SecOper_t *self)
Get the block number of the security block containing this sec operation.
uint64_t BSL_SecOper_GetTargetBlockNum(const BSL_SecOper_t *self)
Get the block number of the target block covered by this security operation.
size_t BSL_SecOper_CountParams(const BSL_SecOper_t *self)
Get the count of parameters contained within this security operation.
const BSL_SecParam_t * BSL_SecOper_GetParamAt(const BSL_SecOper_t *self, size_t index)
Returns a pointer to the Security Parameter at a given index in the list of all paramters.
bool BSL_SecOper_IsConsistent(const BSL_SecOper_t *self)
Returns true if internal consistency and sanity checks pass.
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.
uint64_t BSL_SecParam_GetId(const BSL_SecParam_t *self)
Get parameter ID of this param.
size_t BSL_SecParam_Sizeof(void)
Return size of BSL_SecParam_t struct type.
bool BSL_SecParam_IsParamIDOutput(uint64_t param_id)
Indicates true when this parameter is NOT an implementation-specific security paramter.
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.
size_t BSL_SecResult_Sizeof(void)
Returns size in bytes of BSL_SecResult_t.
int BSL_Data_Deinit(BSL_Data_t *data)
De-initialize a data struct, freeing if necessary.
int BSL_Data_InitBuffer(BSL_Data_t *data, size_t bytelen)
Initialize with an owned buffer of size bytelen.
Contains constants as defined in IETF RFC 9173 (Default Security Context for BPSec)
Wrapper for large, variable-sized buffer holding all working data to compete a BCB operation.
Struct def for HMAC operation context.
Reference to a Bundle owned and stored in the host BPA.
uint64_t block_num
CBOR-decoded block number (should always be > 0)
void * btsd
Pointer to BTSD owned by the host BPA.
size_t btsd_len
Length in bytes of the BTSD pointer.
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.
Concrete definition of library context.