BSL v0.0.0
AMMOS Bundle Protocol Security Library (BSL)
Loading...
Searching...
No Matches
bsl_mock_bpa_encode.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025 The Johns Hopkins University Applied Physics
3 * Laboratory LLC.
4 *
5 * This file is part of the Bundle Protocol Security Library (BSL).
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * This work was performed for the Jet Propulsion Laboratory, California
18 * Institute of Technology, sponsored by the United States Government under
19 * the prime contract 80NM0018D0004 between the Caltech and NASA under
20 * subcontract 1700763.
21 */
22
27#include <BPSecLib_Private.h>
28
29#include "bsl_mock_bpa.h"
30#include "bsl_mock_bpa_encode.h"
31#include "bsl_mock_bpa_crc.h"
32
33int bsl_mock_encode_eid(QCBOREncodeContext *enc, const BSL_HostEID_t *eid)
34{
36 CHKERR1(obj);
37
38 QCBOREncode_OpenArray(enc);
39
40 QCBOREncode_AddUInt64(enc, obj->scheme);
41 switch (obj->scheme)
42 {
44 {
45 const bsl_eid_ipn_ssp_t *ipn = &(obj->ssp.as_ipn);
46 QCBOREncode_OpenArray(enc);
47 switch (ipn->ncomp)
48 {
49 case 2:
50 QCBOREncode_AddUInt64(enc, (ipn->auth_num << 32) | ipn->node_num);
51 QCBOREncode_AddUInt64(enc, ipn->svc_num);
52 break;
53 case 3:
54 QCBOREncode_AddUInt64(enc, ipn->auth_num);
55 QCBOREncode_AddUInt64(enc, ipn->node_num);
56 QCBOREncode_AddUInt64(enc, ipn->svc_num);
57 break;
58 default:
59 // nothing to really do here
60 break;
61 }
62 QCBOREncode_CloseArray(enc);
63 break;
64 }
65 default:
66 {
67 const BSL_Data_t *raw = &(obj->ssp.as_raw);
68 QCBOREncode_AddEncoded(enc, (UsefulBufC) { raw->ptr, raw->len });
69 break;
70 }
71 }
72
73 QCBOREncode_CloseArray(enc);
74 return 0;
75}
76
77static const uint8_t zero_crc[] = { 0, 0, 0, 0 };
78
79int bsl_mock_encode_primary(QCBOREncodeContext *enc, const MockBPA_PrimaryBlock_t *blk)
80{
81 const size_t begin = QCBOREncode_Tell(enc);
82 QCBOREncode_OpenArray(enc);
83
84 QCBOREncode_AddUInt64(enc, blk->version);
85 QCBOREncode_AddUInt64(enc, blk->flags);
86 QCBOREncode_AddUInt64(enc, blk->crc_type);
87
88 bsl_mock_encode_eid(enc, &(blk->dest_eid));
89 bsl_mock_encode_eid(enc, &(blk->src_node_id));
90 bsl_mock_encode_eid(enc, &(blk->report_to_eid));
91
92 QCBOREncode_OpenArray(enc);
93 QCBOREncode_AddUInt64(enc, blk->timestamp.bundle_creation_time);
94 QCBOREncode_AddUInt64(enc, blk->timestamp.seq_num);
95 QCBOREncode_CloseArray(enc);
96
97 QCBOREncode_AddUInt64(enc, blk->lifetime);
98
99 if (blk->flags & BSL_BUNDLE_IS_FRAGMENT)
100 {
101 QCBOREncode_AddUInt64(enc, blk->frag_offset);
102 QCBOREncode_AddUInt64(enc, blk->adu_length);
103 }
104
105 switch (blk->crc_type)
106 {
108 QCBOREncode_AddBytes(enc, (UsefulBufC) { zero_crc, 2 });
109 break;
111 QCBOREncode_AddBytes(enc, (UsefulBufC) { zero_crc, 4 });
112 break;
113 default:
114 // nothing
115 break;
116 }
117
118 QCBOREncode_CloseArray(enc);
119 const size_t end = QCBOREncode_Tell(enc);
120
121 mock_bpa_crc_apply(QCBOREncode_RetrieveOutputStorage(enc), begin, end, blk->crc_type);
122
123 return 0;
124}
125
126int bsl_mock_encode_canonical(QCBOREncodeContext *enc, const MockBPA_CanonicalBlock_t *blk)
127{
128 const size_t begin = QCBOREncode_Tell(enc);
129 QCBOREncode_OpenArray(enc);
130
131 QCBOREncode_AddUInt64(enc, blk->blk_type);
132 QCBOREncode_AddUInt64(enc, blk->blk_num);
133 QCBOREncode_AddUInt64(enc, blk->flags);
134 QCBOREncode_AddUInt64(enc, blk->crc_type);
135 QCBOREncode_AddBytes(enc, (UsefulBufC) { blk->btsd, blk->btsd_len });
136
137 switch (blk->crc_type)
138 {
140 QCBOREncode_AddBytes(enc, (UsefulBufC) { zero_crc, 2 });
141 break;
143 QCBOREncode_AddBytes(enc, (UsefulBufC) { zero_crc, 4 });
144 break;
145 default:
146 // nothing
147 break;
148 }
149
150 QCBOREncode_CloseArray(enc);
151 const size_t end = QCBOREncode_Tell(enc);
152
153 mock_bpa_crc_apply(QCBOREncode_RetrieveOutputStorage(enc), begin, end, blk->crc_type);
154
155 return 0;
156}
157
158// TODO(bvb,brian?) - Ensure deterministic encoding of blocks persuant to RFC9171 rules
159static int _cmp(const void *a, const void *b)
160{
161 // Be careful! This dereferencing took a long time to figure out!
162 const MockBPA_CanonicalBlock_t *block_a = *(const MockBPA_CanonicalBlock_t *const *)a;
163 const MockBPA_CanonicalBlock_t *block_b = *(const MockBPA_CanonicalBlock_t *const *)b;
164 return block_b->blk_type - block_a->blk_type;
165}
166
167int bsl_mock_encode_bundle(QCBOREncodeContext *enc, const MockBPA_Bundle_t *bundle)
168{
169 QCBOREncode_OpenArrayIndefiniteLength(enc);
170
171 bsl_mock_encode_primary(enc, &bundle->primary_block);
172
173 const MockBPA_CanonicalBlock_t *block_ref_array[40] = { 0 };
174 size_t block_id_nitems = 0;
175
176 for (size_t index = 0; index < bundle->block_count; index++)
177 {
178 const MockBPA_CanonicalBlock_t *info = &bundle->blocks[index];
179 block_ref_array[block_id_nitems++] = info;
180 }
181
182 // Sort so that payload block comes at the end/
183 // BCB > BIB > exts > Payload
184 qsort(block_ref_array, block_id_nitems, sizeof(const MockBPA_CanonicalBlock_t *), _cmp);
185
186 // Encode according to the above order.
187 for (size_t index = 0; index < block_id_nitems; index++)
188 {
189 const MockBPA_CanonicalBlock_t *info = block_ref_array[index];
190 bsl_mock_encode_canonical(enc, info);
191 }
192
193 QCBOREncode_CloseArrayIndefiniteLength(enc);
194 return 0;
195}
Single entry-point include file for all of the BPSec Lib (BSL) frontend API.
@ BSL_BUNDLE_IS_FRAGMENT
Set if this bundle is a fragment.
#define CHKERR1(cond)
Return the error value 1 if condition fails.
@ BSL_BUNDLECRCTYPE_16
CRC-16.
@ BSL_BUNDLECRCTYPE_32
CRC-32C.
Declarations for Agent initialization.
void mock_bpa_crc_apply(UsefulBuf buf, size_t begin, size_t end, BSL_BundleCRCType_e crc_type)
Apply a CRC function to an encoded block.
Declarations for BPv7 block CRC handling.
@ BSL_MOCK_EID_IPN
The "ipn" scheme.
int bsl_mock_encode_canonical(QCBOREncodeContext *enc, const MockBPA_CanonicalBlock_t *blk)
This is an overloaded member function, provided for convenience. It differs from the above function o...
int bsl_mock_encode_bundle(QCBOREncodeContext *enc, const MockBPA_Bundle_t *bundle)
This is an overloaded member function, provided for convenience. It differs from the above function o...
int bsl_mock_encode_primary(QCBOREncodeContext *enc, const MockBPA_PrimaryBlock_t *blk)
Encode primary block to a CBOR data.
int bsl_mock_encode_eid(QCBOREncodeContext *enc, const BSL_HostEID_t *eid)
Encode a single EID.
Declarations for bundle and block encoding.
Heap data storage and views.
size_t len
Size of the data buffer.
BSL_DataPtr_t ptr
Pointer to the front of the buffer.
Opaque pointer to BPA-specific Endpoint ID storage.
void * handle
Opaque pointer for BPA backend to use.
Scheme-specific part for IPN scheme.
int ncomp
The number of components when encoded, either 2 or 3.
uint64_t svc_num
The service number component.
uint64_t node_num
The node number component.
uint64_t auth_num
The authority number component.
Struct to be used as a BSL_HostEID_t::handle.
union bsl_mock_eid_t::@0 ssp
Interpreted according to scheme code.
bsl_eid_ipn_ssp_t as_ipn
Used when scheme is BSL_MOCK_EID_IPN.
uint64_t scheme
Code point for EID schemes from .
BSL_Data_t as_raw
Used in all other cases, copied from source.