trussed_core/
api.rs

1//! This (incomplete!) API loosely follows [PKCS#11 v3][pkcs11-v3].
2//!
3//! For constants see [their headers][pkcs11-headers].
4//!
5//! [pkcs11-v3]: https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/pkcs11-base-v3.0.html
6//! [pkcs11-headers]: https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/cs01/include/pkcs11-v3.0/
7
8#[cfg(any(feature = "management-client", feature = "ui-client"))]
9use core::time::Duration;
10
11#[cfg(feature = "ui-client")]
12use crate::types::consent;
13#[cfg(feature = "management-client")]
14use crate::types::reboot;
15#[cfg(feature = "serde-extensions")]
16use crate::types::Bytes;
17#[cfg(any(feature = "attestation-client", feature = "certificate-client"))]
18use crate::types::CertId;
19#[cfg(feature = "counter-client")]
20use crate::types::CounterId;
21#[cfg(any(
22    feature = "certificate-client",
23    feature = "counter-client",
24    feature = "crypto-client",
25    feature = "filesystem-client"
26))]
27use crate::types::Location;
28#[cfg(any(
29    feature = "certificate-client",
30    feature = "crypto-client",
31    feature = "filesystem-client"
32))]
33use crate::types::Message;
34#[cfg(feature = "filesystem-client")]
35use crate::types::{DirEntry, NotBefore, PathBuf, UserAttribute};
36#[cfg(any(feature = "attestation-client", feature = "crypto-client"))]
37use crate::types::{KeyId, Mechanism};
38#[cfg(feature = "crypto-client")]
39use crate::types::{
40    KeySerialization, MediumData, SerializedKey, ShortData, Signature, SignatureSerialization,
41    StorageAttributes,
42};
43
44#[macro_use]
45mod macros;
46
47// TODO: Ideally, we would not need to assign random numbers here
48// The only use for them is to check that the reply type corresponds
49// to the request type in the client.
50//
51// At minimum, we don't want to list the indices (may need proc-macro)
52
53generate_enums! {
54
55    ////////////
56    // Crypto //
57    ////////////
58
59    #[cfg(feature = "crypto-client")]
60    Agree: 1
61    // CreateObject: 2
62    // TODO: why do Decrypt and DeriveKey both have discriminant 3?!
63    #[cfg(feature = "crypto-client")]
64    Decrypt: 3
65    #[cfg(feature = "crypto-client")]
66    DeriveKey: 4
67    #[cfg(feature = "crypto-client")]
68    DeserializeKey: 5
69    #[cfg(feature = "crypto-client")]
70    Encrypt: 6
71    #[cfg(feature = "crypto-client")]
72    Delete: 7
73    // Clear private data from the key
74    // This will not always delete all metadata from storage.
75    // Other backends can retain metadata required for `unwrap_key` to work properly
76    // and delete this metadata only once `delete` is called.
77    #[cfg(feature = "crypto-client")]
78    Clear: 63
79    #[cfg(feature = "crypto-client")]
80    DeleteAllKeys: 25
81    #[cfg(feature = "crypto-client")]
82    Exists: 8
83    // DeriveKeypair: 3
84    // FindObjects: 9
85    #[cfg(feature = "crypto-client")]
86    GenerateKey: 10
87    #[cfg(feature = "crypto-client")]
88    GenerateSecretKey: 11
89    // GenerateKeypair: 6
90    #[cfg(feature = "crypto-client")]
91    Hash: 12
92    // TODO: add ReadDir{First,Next}, not loading data, if needed for efficiency
93    #[cfg(feature = "filesystem-client")]
94    ReadDirFilesFirst: 13
95    #[cfg(feature = "filesystem-client")]
96    ReadDirFilesNext: 14
97    #[cfg(feature = "filesystem-client")]
98    ReadFile: 15
99    #[cfg(feature = "filesystem-client")]
100    Metadata: 26
101    #[cfg(feature = "filesystem-client")]
102    Rename: 27
103    // ReadCounter: 7
104    #[cfg(feature = "crypto-client")]
105    RandomBytes: 16
106    #[cfg(feature = "crypto-client")]
107    SerializeKey: 17
108    #[cfg(feature = "crypto-client")]
109    Sign: 18
110    #[cfg(feature = "filesystem-client")]
111    WriteFile: 19
112    #[cfg(feature = "crypto-client")]
113    UnsafeInjectKey: 20
114    #[cfg(feature = "crypto-client")]
115    UnsafeInjectSharedKey: 21
116    #[cfg(feature = "crypto-client")]
117    UnwrapKey: 22
118    #[cfg(feature = "crypto-client")]
119    Verify: 23
120    #[cfg(feature = "crypto-client")]
121    WrapKey: 24
122
123    #[cfg(feature = "attestation-client")]
124    Attest: 0xFF
125
126    /////////////
127    // Storage //
128    /////////////
129
130    // // CreateDir,    <-- implied by WriteFile
131    #[cfg(feature = "filesystem-client")]
132    ReadDirFirst: 31 //      <-- gets Option<FileType> to restrict to just dir/file DirEntries,
133    #[cfg(feature = "filesystem-client")]
134    ReadDirNext: 32 //      <-- gets Option<FileType> to restrict to just dir/file DirEntries,
135    //                   // returns simplified Metadata
136    // // ReadDirFilesFirst: 23 // <-- returns contents
137    // // ReadDirFilesNext: 24 // <-- returns contents
138    // ReadFile: 25
139    #[cfg(feature = "filesystem-client")]
140    RemoveFile: 33
141    #[cfg(feature = "filesystem-client")]
142    RemoveDir: 36
143    #[cfg(feature = "filesystem-client")]
144    RemoveDirAll: 34
145    // WriteFile: 29
146    #[cfg(feature = "filesystem-client")]
147    LocateFile: 35
148
149    ////////
150    // UI //
151    ////////
152
153    #[cfg(feature = "ui-client")]
154    RequestUserConsent: 41
155    #[cfg(feature = "management-client")]
156    Reboot: 42
157    #[cfg(feature = "management-client")]
158    Uptime: 43
159    #[cfg(feature = "ui-client")]
160    Wink: 44
161    #[cfg(feature = "ui-client")]
162    SetCustomStatus: 45
163
164    //////////////
165    // Counters //
166    //////////////
167
168    #[cfg(feature = "counter-client")]
169    CreateCounter: 50
170    #[cfg(feature = "counter-client")]
171    IncrementCounter: 51
172
173    //////////////////
174    // Certificates //
175    //////////////////
176
177    #[cfg(feature = "certificate-client")]
178    DeleteCertificate: 60
179    #[cfg(feature = "certificate-client")]
180    ReadCertificate: 61
181    #[cfg(feature = "certificate-client")]
182    WriteCertificate: 62
183
184    ///////////
185    // Other //
186    ///////////
187    #[cfg(feature = "filesystem-client")]
188    DebugDumpStore: 0x79
189
190    #[cfg(feature = "serde-extensions")]
191    SerdeExtension: 0x5E
192}
193
194pub trait RequestVariant: Into<Request> + TryFrom<Request, Error = crate::error::Error> {
195    type Reply: ReplyVariant<Request = Self>;
196}
197
198pub trait ReplyVariant: Into<Reply> + TryFrom<Reply, Error = crate::error::Error> {
199    type Request: RequestVariant<Reply = Self>;
200}
201
202pub mod request {
203    #[allow(unused_imports)]
204    use super::*;
205
206    impl_request! {
207        #[cfg(feature = "crypto-client")]
208        Agree:
209            - mechanism: Mechanism
210            - private_key: KeyId
211            - public_key: KeyId
212            - attributes: StorageAttributes
213
214        #[cfg(feature = "attestation-client")]
215        Attest:
216            // only Ed255 + P256
217            - signing_mechanism: Mechanism
218            // only Ed255 + P256
219            - private_key: KeyId
220
221        // // examples:
222        // // - store public keys from external source
223        // // - store certificates
224        // CreateObject:
225        //     - attributes: Attributes
226
227        #[cfg(feature = "filesystem-client")]
228        DebugDumpStore:
229
230        #[cfg(feature = "crypto-client")]
231        Decrypt:
232          - mechanism: Mechanism
233          - key: KeyId
234          - message: Message
235          - associated_data: Message
236          - nonce: ShortData
237          - tag: ShortData
238
239        #[cfg(feature = "crypto-client")]
240        Delete:
241          - key: KeyId
242
243        #[cfg(feature = "crypto-client")]
244        Clear:
245          - key: KeyId
246
247        #[cfg(feature = "crypto-client")]
248        DeleteAllKeys:
249          - location: Location
250
251        // DeleteBlob:
252        //   - prefix: Option<Letters>
253        //   - name: ShortData
254
255        // examples:
256        // - public key from private key
257        // - Diffie-Hellman
258        // - hierarchical deterministic wallet stuff
259        #[cfg(feature = "crypto-client")]
260        DeriveKey:
261            - mechanism: Mechanism
262            - base_key: KeyId
263            // - auxiliary_key: Option<ObjectHandle>
264            - additional_data: Option<MediumData>
265            // - attributes: KeyAttributes
266            - attributes: StorageAttributes
267
268        // DeriveKeypair:
269        //     - mechanism: Mechanism
270        //     - base_key: ObjectHandle
271        //     // - additional_data: Message
272        //     // - attributes: KeyAttributes
273
274        #[cfg(feature = "crypto-client")]
275        DeserializeKey:
276          - mechanism: Mechanism
277          - serialized_key: SerializedKey
278          - format: KeySerialization
279          - attributes: StorageAttributes
280
281        #[cfg(feature = "crypto-client")]
282        Encrypt:
283          - mechanism: Mechanism
284          - key: KeyId
285          - message: Message
286          - associated_data: ShortData
287          - nonce: Option<ShortData>
288
289        #[cfg(feature = "crypto-client")]
290        Exists:
291          - mechanism: Mechanism
292          - key: KeyId
293
294        // FindObjects:
295        //     // - attributes: Attributes
296
297        #[cfg(feature = "crypto-client")]
298        GenerateKey:
299            - mechanism: Mechanism        // -> implies key type
300            // - attributes: KeyAttributes
301            - attributes: StorageAttributes
302
303        #[cfg(feature = "crypto-client")]
304        GenerateSecretKey:
305            - size: usize        // -> implies key type
306            // - attributes: KeyAttributes
307            - attributes: StorageAttributes
308
309        // use GenerateKey + DeriveKey(public-from-private) instead
310        // GenerateKeypair:
311        //     - mechanism: Mechanism
312        //     - attributes: KeyAttributes
313        //     // private_key_template: PrivateKeyTemplate
314        //     // public_key_template: PublicKeyTemplate
315
316        // GetAttributes:
317        //     - object: ObjectHandle
318        //     - attributes: Attributes
319
320        #[cfg(feature = "crypto-client")]
321        Hash:
322          - mechanism: Mechanism
323          - message: Message
324
325        #[cfg(feature = "filesystem-client")]
326        LocateFile:
327          - location: Location
328          - dir: Option<PathBuf>
329          - filename: PathBuf
330
331        #[cfg(feature = "filesystem-client")]
332        ReadDirFilesFirst:
333          - location: Location
334          - dir: PathBuf
335          - user_attribute: Option<UserAttribute>
336
337        #[cfg(feature = "filesystem-client")]
338        ReadDirFilesNext:
339
340        #[cfg(feature = "filesystem-client")]
341        ReadDirFirst:
342          - location: Location
343          - dir: PathBuf
344          - not_before: NotBefore
345
346        #[cfg(feature = "filesystem-client")]
347        ReadDirNext:
348
349        #[cfg(feature = "filesystem-client")]
350        ReadFile:
351          - location: Location
352          - path: PathBuf
353
354        #[cfg(feature = "filesystem-client")]
355        Metadata:
356          - location: Location
357          - path: PathBuf
358
359        #[cfg(feature = "filesystem-client")]
360        Rename:
361          - location: Location
362          - from: PathBuf
363          - to: PathBuf
364
365        #[cfg(feature = "filesystem-client")]
366        RemoveFile:
367          - location: Location
368          - path: PathBuf
369
370        #[cfg(feature = "filesystem-client")]
371        RemoveDir:
372          - location: Location
373          - path: PathBuf
374
375        #[cfg(feature = "filesystem-client")]
376        RemoveDirAll:
377          - location: Location
378          - path: PathBuf
379
380        // use GetAttribute(value) on counter instead
381        // ReadCounter:
382        //     - counter: ObjectHandle
383
384        #[cfg(feature = "crypto-client")]
385        RandomBytes:
386          - count: usize
387
388        #[cfg(feature = "crypto-client")]
389        SerializeKey:
390          - mechanism: Mechanism
391          - key: KeyId
392          - format: KeySerialization
393
394        #[cfg(feature = "crypto-client")]
395        Sign:
396          - mechanism: Mechanism
397          - key: KeyId
398          - message: Message
399          - format: SignatureSerialization
400
401        #[cfg(feature = "filesystem-client")]
402        WriteFile:
403          - location: Location
404          - path: PathBuf
405          - data: Message
406          - user_attribute: Option<UserAttribute>
407
408        #[cfg(feature = "crypto-client")]
409        UnsafeInjectKey:
410          - mechanism: Mechanism        // -> implies key type
411          - raw_key: SerializedKey
412          - attributes: StorageAttributes
413          - format: KeySerialization
414
415        #[cfg(feature = "crypto-client")]
416        UnsafeInjectSharedKey:
417          - location: Location
418          - raw_key: ShortData
419
420        #[cfg(feature = "crypto-client")]
421        UnwrapKey:
422          - mechanism: Mechanism
423          - wrapping_key: KeyId
424          - wrapped_key: Message
425          - associated_data: Message
426          - nonce: ShortData
427          - attributes: StorageAttributes
428
429        #[cfg(feature = "crypto-client")]
430        Verify:
431          - mechanism: Mechanism
432          - key: KeyId
433          - message: Message
434          - signature: Signature
435          - format: SignatureSerialization
436
437        // this should always be an AEAD algorithm
438        #[cfg(feature = "crypto-client")]
439        WrapKey:
440          - mechanism: Mechanism
441          - wrapping_key: KeyId
442          - key: KeyId
443          - associated_data: ShortData
444          - nonce: Option<ShortData>
445
446        #[cfg(feature = "ui-client")]
447        RequestUserConsent:
448          - level: consent::Level
449          - timeout_milliseconds: u32
450
451        #[cfg(feature = "management-client")]
452        Reboot:
453          - to: reboot::To
454
455        #[cfg(feature = "management-client")]
456        Uptime:
457
458        #[cfg(feature = "ui-client")]
459        Wink:
460          - duration: Duration
461
462        #[cfg(feature = "ui-client")]
463        SetCustomStatus:
464          - status: u8
465
466        #[cfg(feature = "counter-client")]
467        CreateCounter:
468          - location: Location
469
470        #[cfg(feature = "counter-client")]
471        IncrementCounter:
472          - id: CounterId
473
474        #[cfg(feature = "certificate-client")]
475        DeleteCertificate:
476          - id: CertId
477
478        #[cfg(feature = "certificate-client")]
479        ReadCertificate:
480          - id: CertId
481
482        #[cfg(feature = "certificate-client")]
483        WriteCertificate:
484          - location: Location
485          - der: Message
486
487        #[cfg(feature = "serde-extensions")]
488        SerdeExtension:
489          - id: u8
490          - request: Bytes<{ crate::config::SERDE_EXTENSION_REQUEST_LENGTH }>
491    }
492}
493
494pub mod reply {
495    #[allow(unused_imports)]
496    use super::*;
497
498    // type ObjectHandles = Vec<ObjectHandle, config::MAX_OBJECT_HANDLES>;
499
500    impl_reply! {
501        // could return either a SharedSecretXY or a SymmetricKeyXY,
502        // depending on mechanism
503        // e.g.: P256Raw -> SharedSecret32
504        //       P256Sha256 -> SymmetricKey32
505        #[cfg(feature = "crypto-client")]
506        Agree:
507            - shared_secret: KeyId
508
509        #[cfg(feature = "attestation-client")]
510        Attest:
511            - certificate: CertId
512
513        // CreateObject:
514        //     - object: ObjectHandle
515
516        // FindObjects:
517        //     - objects: Vec<ObjectHandle, config::MAX_OBJECT_HANDLES>
518        //     // can be higher than capacity of vector
519        //     - num_objects: usize
520
521        #[cfg(feature = "filesystem-client")]
522        DebugDumpStore:
523
524        #[cfg(feature = "crypto-client")]
525        Decrypt:
526            - plaintext: Option<Message>
527
528        #[cfg(feature = "crypto-client")]
529        Delete:
530            - success: bool
531
532        #[cfg(feature = "crypto-client")]
533        Clear:
534            - success: bool
535
536        #[cfg(feature = "crypto-client")]
537        DeleteAllKeys:
538            - count: usize
539
540        #[cfg(feature = "crypto-client")]
541        DeriveKey:
542            - key: KeyId
543
544        // DeriveKeypair:
545        //     - private_key: ObjectHandle
546        //     - public_key: ObjectHandle
547
548        #[cfg(feature = "crypto-client")]
549        DeserializeKey:
550            - key: KeyId
551
552        #[cfg(feature = "crypto-client")]
553        Encrypt:
554            - ciphertext: Message
555            - nonce: ShortData
556            - tag: ShortData
557
558        #[cfg(feature = "crypto-client")]
559        Exists:
560            - exists: bool
561
562        #[cfg(feature = "crypto-client")]
563        GenerateKey:
564            - key: KeyId
565
566        #[cfg(feature = "crypto-client")]
567        GenerateSecretKey:
568            - key: KeyId
569
570        // GenerateKeypair:
571        //     - private_key: KeyId
572        //     - public_key: KeyId
573
574        #[cfg(feature = "crypto-client")]
575        Hash:
576          - hash: ShortData
577
578        #[cfg(feature = "filesystem-client")]
579        LocateFile:
580          - path: Option<PathBuf>
581
582        #[cfg(feature = "filesystem-client")]
583        ReadDirFilesFirst:
584          - data: Option<Message>
585
586        #[cfg(feature = "filesystem-client")]
587        ReadDirFilesNext:
588          - data: Option<Message>
589
590        #[cfg(feature = "filesystem-client")]
591        ReadDirFirst:
592          - entry: Option<DirEntry>
593
594        #[cfg(feature = "filesystem-client")]
595        ReadDirNext:
596          - entry: Option<DirEntry>
597
598        #[cfg(feature = "filesystem-client")]
599        ReadFile:
600          - data: Message
601
602        #[cfg(feature = "filesystem-client")]
603        Metadata:
604          - metadata: Option<crate::types::Metadata>
605
606        #[cfg(feature = "filesystem-client")]
607        Rename:
608
609        #[cfg(feature = "filesystem-client")]
610        RemoveDir:
611
612        #[cfg(feature = "filesystem-client")]
613        RemoveDirAll:
614          - count: usize
615
616        #[cfg(feature = "filesystem-client")]
617        RemoveFile:
618
619        // ReadCounter:
620        //     - counter: u32
621
622        #[cfg(feature = "crypto-client")]
623        RandomBytes:
624            - bytes: Message
625
626        #[cfg(feature = "crypto-client")]
627        SerializeKey:
628            - serialized_key: SerializedKey
629
630        #[cfg(feature = "crypto-client")]
631        Sign:
632            - signature: Signature
633
634        #[cfg(feature = "filesystem-client")]
635        WriteFile:
636
637        #[cfg(feature = "crypto-client")]
638        Verify:
639            - valid: bool
640
641        #[cfg(feature = "crypto-client")]
642        UnsafeInjectKey:
643            - key: KeyId
644
645        #[cfg(feature = "crypto-client")]
646        UnsafeInjectSharedKey:
647            - key: KeyId
648
649        #[cfg(feature = "crypto-client")]
650        UnwrapKey:
651            - key: Option<KeyId>
652
653        #[cfg(feature = "crypto-client")]
654        WrapKey:
655            - wrapped_key: Message
656
657        // UI
658        #[cfg(feature = "ui-client")]
659        RequestUserConsent:
660            - result: consent::Result
661
662        #[cfg(feature = "management-client")]
663        Reboot:
664
665        #[cfg(feature = "management-client")]
666        Uptime:
667          - uptime: Duration
668
669        #[cfg(feature = "ui-client")]
670        Wink:
671
672        #[cfg(feature = "ui-client")]
673        SetCustomStatus:
674
675        #[cfg(feature = "counter-client")]
676        CreateCounter:
677          - id: CounterId
678
679        #[cfg(feature = "counter-client")]
680        IncrementCounter:
681          - counter: u128
682
683        #[cfg(feature = "certificate-client")]
684        DeleteCertificate:
685
686        #[cfg(feature = "certificate-client")]
687        ReadCertificate:
688          - der: Message
689
690        #[cfg(feature = "certificate-client")]
691        WriteCertificate:
692          - id: CertId
693
694        #[cfg(feature = "serde-extensions")]
695        SerdeExtension:
696          - reply: Bytes<{ crate::config::SERDE_EXTENSION_REPLY_LENGTH }>
697    }
698}