1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
/** @file */
/** @ingroup oscore_api
* @addtogroup oscore_msg OSCORE message API
*
* @brief API for manipulating OSCORE messages
*
* These functions implement the same abstract interface as @ref
* oscore_native_msg, but act on encrypted (more precisely: plaintext in
* preparation for encryption in place, or plaintext after in-place
* decryption) messages.
*
* @note While in the backend interface there is a @ref oscore_msg_native_t
* type that is typically some kind of pointer and supplied directly to the
* @ref oscore_msg_native_set_code and similar functions, OSCORE's message
* type is a large struct and passed into the equivalent @ref
* oscore_msg_protected_set_code as a reference. This is because library parts
* other than the message API (for example the setup of an encrypted message),
* type needs to be allocated on the stack. The message API itself always uses
* it via pointers, so if you are looking for a precise equivalent to @ref
* oscore_msg_native_t, it's not `oscore_msg_protected_t` but
* `&oscore_msg_protected_t`.
*
* @todo Link to "setup of an encrypted message" API
*
* @{
*/
/** @brief Tracking helper for CoAP-encoded option sequences
*
* This struct is used to keep track of the Class-E options being written
* inside the plaintext, and can be used for tracking Class-I options as well.
*
* @private
*/
;
/** @brief Flags used inside OSCORE messages
*
* These flags keep some state about a message, especially about which fields
* are initialized.
*
* This enum is used for flag value to be OR-ed together. Valid flag values may
* be the union of several named enum states.
*
* @private
*/
;
/** @brief OSCORE protected CoAP message
*
* @todo This struct may need splitting up according to read/write state
*
* This structure represents a CoAP message built ready for in-place
* encryption, or decrypted in-place. Its outer options are placed as options
* of its backend. Its code, inner options, payload and padding for the AEAD
* tag are placed in the backend's payload according to the OSCORE
* specification.
*/
typedef struct oscore_msg_protected_t;
/** @brief OSCORE message operation error type
*
* These errors are returned by functions manipulating a @ref oscore_msg_protected_t.
*/
typedef enum oscore_msgerr_protected_t;
/** @brief Iterator (cursor) over a protected CoAP message
*/
typedef struct oscore_msg_protected_optiter_t;
/** Retrieve the inner CoAP code (request method or response code) from a protected message */
uint8_t ;
/** Set the inner CoAP code (request method or response code) of a protected message */
void ;
/** @brief Append an option to a protected CoAP message
*
* @param[inout] msg Message to append to
* @param[in] option_number Option number of the new option
* @param[in] value Bytes to be added in the new option
* @param[in] value_len Number of bytes in the new option
*
* Depending on the option's protection class (U, I or E), the option is
* included in the appropriate section of the message.
*
* Valid reasons for this to return an unsuccessful response include space
* inside the message, options being written in the wrong order or payload
* having been written to the message.
*/
oscore_msgerr_protected_t ;
/** @brief Update an single occurrence of an option in a protected CoAP message
*
* @param[inout] msg Message to update
* @param[in] option_number Option number of the new option
* @param[in] occurrence Index inside the list of options of the same option number to update (starting at zero)
* @param[in] value Bytes to be added in the new option
* @param[in] value_len Number of bytes in the new option
*
* This may return unsuccessfully if there was no such option, or if the
* @p value_len given is not equal to that option's length. Some options
* require special handling by OSCORE (eg. the observation option) and can not
* be updated this way.
*/
oscore_msgerr_protected_t ;
/** @brief Set up an iterator over a protected CoAP message
*
* Set up the previously uninitialized @p iter on which
* @ref oscore_msg_protected_optiter_next can be called.
*
* @param[in] msg Message to iterate over
* @param[out] iter Caller-allocated (previously unininitialized) iterator
* (cursor) to initialize
*
* Callers of this function must call @ref oscore_msg_protected_optiter_finish
* when done (fetching any errors that occurred) and before attempting to alter
* the message.
*/
void ;
/** @brief Iterate through options of a CoAP protected message
*
* @param[in] msg Message to iterate over
* @param[inout] iter Iterator (cursor) that is read and incremented
* @param[out] option_number Number of the read CoAP option
* @param[out] value Data inside the read CoAP option
* @param[out] value_len Number of bytes inside the read CoAP option
*
* If there is a next option to be read in the message, set @p value, @p
* value_len and @p option_number to that option's data and return true.
*
* If the iterator has been exhausted or failed, return false.
*/
bool ;
/** @brief Clean up an option iterator
*
* Close the iterator previously created by @ref oscore_msg_protected_optiter_init.
*
* @param[in] msg Message that was being iterated over
* @param[inout] iter Iterator (cursor) that will not be used any more after
* this invocation
*
* If any errors were encountered during the iteration, they are returned from
* this function. That is to keep the iteration loop simple, and to have a
* clear place to handle clean-up. Errors can be encountered when inner options
* are encoded invalidly, or when critical Class E options are present in the
* outer options.
*/
oscore_msgerr_protected_t ;
/** @brief Provide address and size information to writable payload
*
* @param[inout] msg Message whose payload is accessed
* @param[out] payload Address where message payload can be written to
* @param[out] payload_len Size of writable payload
*
* This modifies the message as it ends the possibility of adding options
* (after having added any outstanding automatically inserted options like the
* OSCORE or the inner Observe option).
*
* This function can fail if the encoding of the inner options is erroneous (as
* their encoding is not checked at decryption time). It will not fail if the
* options have been iterated over successfully.
*
* It could be argued that this can be made infallible and could return
* arbitrary zero-length memory as the semantics of the payload can't be
* comprehended exhaustively having gone through the options. Given that this
* has little cost and large benefits in debugging, this function is allowed an
* error code.
*/
oscore_msgerr_protected_t ;
/** @brief Shorten the payload to a given length
*
* @param[inout] msg Message whose payload is accessed
* @param[in] payload_len Size of writable payload
*
* Reduce the payload length of the message to the given size. After this, no
* further @ref oscore_msg_protected_append_option calls are possible (as this,
* like @ref oscore_msg_protected_map_payload, flushes the outstanding
* automatically inserted options), and then trims the underlying native
* message.
*
* The given size must be at most the @p payload_len obtained in a
* @ref oscore_msg_protected_map_payload call; zero may be passed in even
* without having called that.
*
*/
oscore_msgerr_protected_t ;
/** Return true if an error type indicates an unsuccessful operation */
bool ;
/** @} */